Changeset 201798 in webkit


Ignore:
Timestamp:
Jun 8, 2016 12:37:08 AM (8 years ago)
Author:
adam.bergkvist@ericsson.com
Message:

WebRTC: Imlement MediaEndpointPeerConnection::setLocalDescription()
https://bugs.webkit.org/show_bug.cgi?id=158190

Reviewed by Eric Carlson.

Source/WebCore:

Add implementation for MediaEndpointPeerConnection::setLocalDescription. This function
parses the input SDP, configures the media backend and updates the
RTCPeerConnection state.

This change adds MediaEndpointSessionDescription which is an object representation
of an RTCSessionDescription (which contains an SDP string).

Test: fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html

  • CMakeLists.txt:

Add MediaEndpointSessionDescription.

  • Modules/mediastream/MediaEndpointPeerConnection.cpp:

(WebCore::hasUnassociatedTransceivers):
(WebCore::MediaEndpointPeerConnection::createOfferTask):
(WebCore::MediaEndpointPeerConnection::setLocalDescription):
(WebCore::MediaEndpointPeerConnection::setLocalDescriptionTask):
Add implementation.
(WebCore::MediaEndpointPeerConnection::localDescription):
(WebCore::MediaEndpointPeerConnection::currentLocalDescription):
(WebCore::MediaEndpointPeerConnection::pendingLocalDescription):
(WebCore::MediaEndpointPeerConnection::localDescriptionTypeValidForState):
(WebCore::MediaEndpointPeerConnection::internalLocalDescription):
(WebCore::MediaEndpointPeerConnection::createRTCSessionDescription):

  • Modules/mediastream/MediaEndpointPeerConnection.h:
  • Modules/mediastream/MediaEndpointSessionDescription.cpp: Added.

(WebCore::MediaEndpointSessionDescription::create):
(WebCore::MediaEndpointSessionDescription::toRTCSessionDescription):
(WebCore::MediaEndpointSessionDescription::typeString):
(WebCore::MediaEndpointSessionDescription::isLaterThan):

  • Modules/mediastream/MediaEndpointSessionDescription.h: Added.

(WebCore::MediaEndpointSessionDescription::~MediaEndpointSessionDescription):
(WebCore::MediaEndpointSessionDescription::type):
(WebCore::MediaEndpointSessionDescription::configuration):
(WebCore::MediaEndpointSessionDescription::MediaEndpointSessionDescription):

  • WebCore.xcodeproj/project.pbxproj:

Add MediaEndpointSessionDescription.

LayoutTests:

Add new test for RTCPeerConnection.setLocalDescription.

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

Set two local offers as local descriptions and inspect the state changes. Also set some
descriptions with bad types.

  • platform/mac/TestExpectations:

Skip the above test for mac (not building with WEB_RTC)

Location:
trunk
Files:
4 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r201791 r201798  
     12016-06-08  Adam Bergkvist  <adam.bergkvist@ericsson.com>
     2
     3        WebRTC: Imlement MediaEndpointPeerConnection::setLocalDescription()
     4        https://bugs.webkit.org/show_bug.cgi?id=158190
     5
     6        Reviewed by Eric Carlson.
     7
     8        Add new test for RTCPeerConnection.setLocalDescription.
     9
     10        * fast/mediastream/RTCPeerConnection-setLocalDescription-offer-expected.txt: Added.
     11        * fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html: Added.
     12        Set two local offers as local descriptions and inspect the state changes. Also set some
     13        descriptions with bad types.
     14        * platform/mac/TestExpectations:
     15        Skip the above test for mac (not building with WEB_RTC)
     16
    1172016-06-07  Chris Dumez  <cdumez@apple.com>
    218
  • trunk/LayoutTests/platform/mac/TestExpectations

    r201753 r201798  
    191191fast/mediastream/RTCRtpSender-replaceTrack.html
    192192fast/mediastream/RTCSessionDescription.html
     193fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html
    193194
    194195# Asserts in debug.
  • trunk/Source/WebCore/CMakeLists.txt

    r201659 r201798  
    911911    Modules/mediastream/MediaDevicesRequest.cpp
    912912    Modules/mediastream/MediaEndpointPeerConnection.cpp
     913    Modules/mediastream/MediaEndpointSessionDescription.cpp
    913914    Modules/mediastream/MediaSourceSettings.cpp
    914915    Modules/mediastream/MediaStream.cpp
  • trunk/Source/WebCore/ChangeLog

    r201796 r201798  
     12016-06-08  Adam Bergkvist  <adam.bergkvist@ericsson.com>
     2
     3        WebRTC: Imlement MediaEndpointPeerConnection::setLocalDescription()
     4        https://bugs.webkit.org/show_bug.cgi?id=158190
     5
     6        Reviewed by Eric Carlson.
     7
     8        Add implementation for MediaEndpointPeerConnection::setLocalDescription. This function
     9        parses the input SDP, configures the media backend and updates the
     10        RTCPeerConnection state.
     11
     12        This change adds MediaEndpointSessionDescription which is an object representation
     13        of an RTCSessionDescription (which contains an SDP string).
     14
     15        Test: fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html
     16
     17        * CMakeLists.txt:
     18        Add MediaEndpointSessionDescription.
     19        * Modules/mediastream/MediaEndpointPeerConnection.cpp:
     20        (WebCore::hasUnassociatedTransceivers):
     21        (WebCore::MediaEndpointPeerConnection::createOfferTask):
     22        (WebCore::MediaEndpointPeerConnection::setLocalDescription):
     23        (WebCore::MediaEndpointPeerConnection::setLocalDescriptionTask):
     24        Add implementation.
     25        (WebCore::MediaEndpointPeerConnection::localDescription):
     26        (WebCore::MediaEndpointPeerConnection::currentLocalDescription):
     27        (WebCore::MediaEndpointPeerConnection::pendingLocalDescription):
     28        (WebCore::MediaEndpointPeerConnection::localDescriptionTypeValidForState):
     29        (WebCore::MediaEndpointPeerConnection::internalLocalDescription):
     30        (WebCore::MediaEndpointPeerConnection::createRTCSessionDescription):
     31        * Modules/mediastream/MediaEndpointPeerConnection.h:
     32        * Modules/mediastream/MediaEndpointSessionDescription.cpp: Added.
     33        (WebCore::MediaEndpointSessionDescription::create):
     34        (WebCore::MediaEndpointSessionDescription::toRTCSessionDescription):
     35        (WebCore::MediaEndpointSessionDescription::typeString):
     36        (WebCore::MediaEndpointSessionDescription::isLaterThan):
     37        * Modules/mediastream/MediaEndpointSessionDescription.h: Added.
     38        (WebCore::MediaEndpointSessionDescription::~MediaEndpointSessionDescription):
     39        (WebCore::MediaEndpointSessionDescription::type):
     40        (WebCore::MediaEndpointSessionDescription::configuration):
     41        (WebCore::MediaEndpointSessionDescription::MediaEndpointSessionDescription):
     42        * WebCore.xcodeproj/project.pbxproj:
     43        Add MediaEndpointSessionDescription.
     44
    1452016-06-07  Carlos Garcia Campos  <cgarcia@igalia.com>
    246
  • trunk/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp

    r201794 r201798  
    3434#include "MediaEndpointPeerConnection.h"
    3535
     36#include "Event.h"
    3637#include "JSRTCSessionDescription.h"
    3738#include "MediaEndpointSessionConfiguration.h"
    3839#include "MediaStreamTrack.h"
     40#include "PeerMediaDescription.h"
    3941#include "RTCOfferAnswerOptions.h"
    4042#include "RTCRtpTransceiver.h"
     
    9698}
    9799
     100static bool hasUnassociatedTransceivers(const RtpTransceiverVector& transceivers)
     101{
     102    return matchTransceiver(transceivers, [] (RTCRtpTransceiver& current) {
     103        return current.mid().isNull() && !current.stopped();
     104    });
     105}
     106
    98107void MediaEndpointPeerConnection::runTask(NoncopyableFunction<void ()>&& task)
    99108{
     
    129138        return;
    130139
    131     RefPtr<MediaEndpointSessionConfiguration> configurationSnapshot = MediaEndpointSessionConfiguration::create();
     140    MediaEndpointSessionDescription* localDescription = internalLocalDescription();
     141    RefPtr<MediaEndpointSessionConfiguration> configurationSnapshot = localDescription ?
     142        localDescription->configuration()->clone() : MediaEndpointSessionConfiguration::create();
    132143
    133144    configurationSnapshot->setSessionVersion(m_sdpOfferSessionVersion++);
     
    201212void MediaEndpointPeerConnection::setLocalDescription(RTCSessionDescription& description, VoidPromise&& promise)
    202213{
    203     UNUSED_PARAM(description);
    204 
    205     notImplemented();
    206 
    207     promise.reject(NOT_SUPPORTED_ERR);
     214    runTask([this, protectedDescription = RefPtr<RTCSessionDescription>(&description), protectedPromise = WTFMove(promise)]() mutable {
     215        setLocalDescriptionTask(WTFMove(protectedDescription), protectedPromise);
     216    });
     217}
     218
     219void MediaEndpointPeerConnection::setLocalDescriptionTask(RefPtr<RTCSessionDescription>&& description, VoidPromise& promise)
     220{
     221    if (m_client->internalSignalingState() == SignalingState::Closed)
     222        return;
     223
     224    ExceptionCodeWithMessage exception;
     225    auto newDescription = MediaEndpointSessionDescription::create(WTFMove(description), *m_sdpProcessor, exception);
     226    if (exception.code) {
     227        promise.reject(exception.code, exception.message);
     228        return;
     229    }
     230
     231    if (!localDescriptionTypeValidForState(newDescription->type())) {
     232        promise.reject(INVALID_STATE_ERR, "Description type incompatible with current signaling state");
     233        return;
     234    }
     235
     236    const RtpTransceiverVector& transceivers = m_client->getTransceivers();
     237    const MediaDescriptionVector& mediaDescriptions = newDescription->configuration()->mediaDescriptions();
     238    MediaEndpointSessionDescription* localDescription = internalLocalDescription();
     239    unsigned previousNumberOfMediaDescriptions = localDescription ? localDescription->configuration()->mediaDescriptions().size() : 0;
     240    bool hasNewMediaDescriptions = mediaDescriptions.size() > previousNumberOfMediaDescriptions;
     241    bool isInitiator = newDescription->type() == RTCSessionDescription::SdpType::Offer;
     242
     243    if (hasNewMediaDescriptions) {
     244        MediaEndpoint::UpdateResult result = m_mediaEndpoint->updateReceiveConfiguration(newDescription->configuration(), isInitiator);
     245
     246        if (result == MediaEndpoint::UpdateResult::SuccessWithIceRestart) {
     247            if (m_client->internalIceGatheringState() != IceGatheringState::Gathering)
     248                m_client->updateIceGatheringState(IceGatheringState::Gathering);
     249
     250            if (m_client->internalIceConnectionState() != IceConnectionState::Completed)
     251                m_client->updateIceConnectionState(IceConnectionState::Connected);
     252
     253            LOG_ERROR("ICE restart is not implemented");
     254            notImplemented();
     255
     256        } else if (result == MediaEndpoint::UpdateResult::Failed) {
     257            promise.reject(OperationError, "Unable to apply session description");
     258            return;
     259        }
     260
     261        // Associate media descriptions with transceivers (set provisional mid to 'final' mid).
     262        for (unsigned i = previousNumberOfMediaDescriptions; i < mediaDescriptions.size(); ++i) {
     263            PeerMediaDescription& mediaDescription = *mediaDescriptions[i];
     264
     265            RTCRtpTransceiver* transceiver = matchTransceiver(transceivers, [&mediaDescription] (RTCRtpTransceiver& current) {
     266                return current.provisionalMid() == mediaDescription.mid();
     267            });
     268            if (transceiver)
     269                transceiver->setMid(transceiver->provisionalMid());
     270        }
     271    }
     272
     273    if (!hasUnassociatedTransceivers(transceivers))
     274        clearNegotiationNeededState();
     275
     276    SignalingState newSignalingState;
     277
     278    // Update state and local descriptions according to setLocal/RemoteDescription processing model
     279    switch (newDescription->type()) {
     280    case RTCSessionDescription::SdpType::Offer:
     281        m_pendingLocalDescription = newDescription;
     282        newSignalingState = SignalingState::HaveLocalOffer;
     283        break;
     284
     285    case RTCSessionDescription::SdpType::Answer:
     286        m_currentLocalDescription = newDescription;
     287        m_pendingLocalDescription = nullptr;
     288        newSignalingState = SignalingState::Stable;
     289        break;
     290
     291    case RTCSessionDescription::SdpType::Rollback:
     292        m_pendingLocalDescription = nullptr;
     293        newSignalingState = SignalingState::Stable;
     294        break;
     295
     296    case RTCSessionDescription::SdpType::Pranswer:
     297        m_pendingLocalDescription = newDescription;
     298        newSignalingState = SignalingState::HaveLocalPrAnswer;
     299        break;
     300    }
     301
     302    if (newSignalingState != m_client->internalSignalingState()) {
     303        m_client->setSignalingState(newSignalingState);
     304        m_client->fireEvent(Event::create(eventNames().signalingstatechangeEvent, false, false));
     305    }
     306
     307    if (m_client->internalIceGatheringState() == IceGatheringState::New && mediaDescriptions.size())
     308        m_client->updateIceGatheringState(IceGatheringState::Gathering);
     309
     310    if (m_client->internalSignalingState() == SignalingState::Stable && m_negotiationNeeded)
     311        m_client->scheduleNegotiationNeededEvent();
     312
     313    promise.resolve(nullptr);
    208314}
    209315
    210316RefPtr<RTCSessionDescription> MediaEndpointPeerConnection::localDescription() const
    211317{
    212     notImplemented();
    213 
    214     return nullptr;
     318    return createRTCSessionDescription(internalLocalDescription());
    215319}
    216320
    217321RefPtr<RTCSessionDescription> MediaEndpointPeerConnection::currentLocalDescription() const
    218322{
    219     notImplemented();
    220 
    221     return nullptr;
     323    return createRTCSessionDescription(m_currentLocalDescription.get());
    222324}
    223325
    224326RefPtr<RTCSessionDescription> MediaEndpointPeerConnection::pendingLocalDescription() const
    225327{
    226     notImplemented();
    227 
    228     return nullptr;
     328    return createRTCSessionDescription(m_pendingLocalDescription.get());
    229329}
    230330
     
    315415}
    316416
     417bool MediaEndpointPeerConnection::localDescriptionTypeValidForState(RTCSessionDescription::SdpType type) const
     418{
     419    switch (m_client->internalSignalingState()) {
     420    case SignalingState::Stable:
     421        return type == RTCSessionDescription::SdpType::Offer;
     422    case SignalingState::HaveLocalOffer:
     423        return type == RTCSessionDescription::SdpType::Offer;
     424    case SignalingState::HaveRemoteOffer:
     425        return type == RTCSessionDescription::SdpType::Answer || type == RTCSessionDescription::SdpType::Pranswer;
     426    case SignalingState::HaveLocalPrAnswer:
     427        return type == RTCSessionDescription::SdpType::Answer || type == RTCSessionDescription::SdpType::Pranswer;
     428    default:
     429        return false;
     430    };
     431
     432    ASSERT_NOT_REACHED();
     433    return false;
     434}
     435
     436MediaEndpointSessionDescription* MediaEndpointPeerConnection::internalLocalDescription() const
     437{
     438    return m_pendingLocalDescription ? m_pendingLocalDescription.get() : m_currentLocalDescription.get();
     439}
     440
     441RefPtr<RTCSessionDescription> MediaEndpointPeerConnection::createRTCSessionDescription(MediaEndpointSessionDescription* description) const
     442{
     443    return description ? description->toRTCSessionDescription(*m_sdpProcessor) : nullptr;
     444}
     445
    317446void MediaEndpointPeerConnection::gotDtlsFingerprint(const String& fingerprint, const String& fingerprintFunction)
    318447{
  • trunk/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h

    r201728 r201798  
    11/*
    2  * Copyright (C) 2015 Ericsson AB. All rights reserved.
     2 * Copyright (C) 2015, 2016 Ericsson AB. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3535
    3636#include "MediaEndpoint.h"
     37#include "MediaEndpointSessionDescription.h"
    3738#include "NotImplemented.h"
    3839#include "PeerConnectionBackend.h"
    39 #include "RTCSessionDescription.h"
    4040#include <wtf/NoncopyableFunction.h>
    4141#include <wtf/RefPtr.h>
     
    4444
    4545class MediaStreamTrack;
     46class PeerMediaDescription;
    4647class SDPProcessor;
    4748
     49typedef Vector<RefPtr<PeerMediaDescription>> MediaDescriptionVector;
    4850typedef Vector<RefPtr<RTCRtpSender>> RtpSenderVector;
    4951typedef Vector<RefPtr<RTCRtpTransceiver>> RtpTransceiverVector;
     
    8688    void createOfferTask(RTCOfferOptions&, PeerConnection::SessionDescriptionPromise&);
    8789
     90    void setLocalDescriptionTask(RefPtr<RTCSessionDescription>&&, PeerConnection::VoidPromise&);
     91
     92    bool localDescriptionTypeValidForState(RTCSessionDescription::SdpType) const;
     93
     94    MediaEndpointSessionDescription* internalLocalDescription() const;
     95    RefPtr<RTCSessionDescription> createRTCSessionDescription(MediaEndpointSessionDescription*) const;
     96
    8897    // MediaEndpointClient
    8998    void gotDtlsFingerprint(const String& fingerprint, const String& fingerprintFunction) override;
     
    108117    String m_dtlsFingerprintFunction;
    109118    unsigned m_sdpOfferSessionVersion { 0 };
     119
     120    RefPtr<MediaEndpointSessionDescription> m_currentLocalDescription;
     121    RefPtr<MediaEndpointSessionDescription> m_pendingLocalDescription;
     122
     123    bool m_negotiationNeeded { false };
    110124};
    111125
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r201759 r201798  
    23872387                5E2C437B1BCF9A570001E2BC /* RTCPeerConnectionBuiltins.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E2C43761BCF9A0B0001E2BC /* RTCPeerConnectionBuiltins.h */; settings = {ATTRIBUTES = (Private, ); }; };
    23882388                5E2C437C1BCF9A840001E2BC /* RTCPeerConnectionInternalsBuiltins.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E2C43791BCF9A0B0001E2BC /* RTCPeerConnectionInternalsBuiltins.h */; settings = {ATTRIBUTES = (Private, ); }; };
     2389                5E4EAB041D07166A0006A184 /* MediaEndpointSessionDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E4EAB031D07164C0006A184 /* MediaEndpointSessionDescription.h */; };
     2390                5E4EAB051D07166E0006A184 /* MediaEndpointSessionDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E4EAB021D07164C0006A184 /* MediaEndpointSessionDescription.cpp */; };
    23892391                5E5E2B131CFC3E70000C0D85 /* RTCRtpTransceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E5E2B101CFC3E4B000C0D85 /* RTCRtpTransceiver.cpp */; };
    23902392                5E5E2B141CFC3E75000C0D85 /* RTCRtpTransceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E5E2B111CFC3E4B000C0D85 /* RTCRtpTransceiver.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    99969998                5E2C43781BCF9A0B0001E2BC /* RTCPeerConnectionInternalsBuiltins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTCPeerConnectionInternalsBuiltins.cpp; sourceTree = "<group>"; };
    99979999                5E2C43791BCF9A0B0001E2BC /* RTCPeerConnectionInternalsBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCPeerConnectionInternalsBuiltins.h; sourceTree = "<group>"; };
     10000                5E4EAB021D07164C0006A184 /* MediaEndpointSessionDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaEndpointSessionDescription.cpp; sourceTree = "<group>"; };
     10001                5E4EAB031D07164C0006A184 /* MediaEndpointSessionDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaEndpointSessionDescription.h; sourceTree = "<group>"; };
    999810002                5E5E2B101CFC3E4B000C0D85 /* RTCRtpTransceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTCRtpTransceiver.cpp; sourceTree = "<group>"; };
    999910003                5E5E2B111CFC3E4B000C0D85 /* RTCRtpTransceiver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCRtpTransceiver.h; sourceTree = "<group>"; };
     
    1540815412                                5E16A2E21BFA64FB0029A21E /* MediaEndpointPeerConnection.cpp */,
    1540915413                                5E16A2E31BFA64FB0029A21E /* MediaEndpointPeerConnection.h */,
     15414                                5E4EAB021D07164C0006A184 /* MediaEndpointSessionDescription.cpp */,
     15415                                5E4EAB031D07164C0006A184 /* MediaEndpointSessionDescription.h */,
    1541015416                                07C59B6517F784BA000FBCBB /* MediaSourceSettings.cpp */,
    1541115417                                07C59B6617F784BA000FBCBB /* MediaSourceSettings.h */,
     
    2707827084                                E1C362EF0EAF2AA9007410BC /* JSWorkerLocation.h in Headers */,
    2707927085                                E1271A580EEECDE400F61213 /* JSWorkerNavigator.h in Headers */,
     27086                                5E4EAB041D07166A0006A184 /* MediaEndpointSessionDescription.h in Headers */,
    2708027087                                7C4C96DD1AD4483500365A60 /* JSWritableStream.h in Headers */,
    2708127088                                8358CB701C53277500E0C2D8 /* JSXMLDocument.h in Headers */,
     
    3163531642                                BCEF447D0E674806001C1287 /* StyleGeneratedImage.cpp in Sources */,
    3163631643                                A10DC76A14747BAB005E2471 /* StyleGridData.cpp in Sources */,
     31644                                5E4EAB051D07166E0006A184 /* MediaEndpointSessionDescription.cpp in Sources */,
    3163731645                                A110DB9D14F5DF8700A03B93 /* StyleGridItemData.cpp in Sources */,
    3163831646                                BC2273030E82F1E600E7F975 /* StyleInheritedData.cpp in Sources */,
Note: See TracChangeset for help on using the changeset viewer.