Changeset 214357 in webkit


Ignore:
Timestamp:
Mar 24, 2017 11:01:18 AM (7 years ago)
Author:
commit-queue@webkit.org
Message:

Add libwebrtc backend support for RTCRtpSender::replaceTrack
https://bugs.webkit.org/show_bug.cgi?id=169841

Patch by Youenn Fablet <youenn@apple.com> on 2017-03-24
Reviewed by Alex Christensen.

Source/WebCore:

Tests: webrtc/audio-replace-track.html

webrtc/video-replace-track.html

Adding support for replaceTrack for audio and video sources.
Replacing tracks will always succeed for audio sources.
For video tracks, it will only succeed if the video resolution is not greater.
LibWebRTCPeerConnectionBackend will delegate the track replacing by replacing the source of the outgoing sources with the source wrapped in the replacing track.

Video test is not fully passing as size constraints for mock video sources are not providing the right video stream resolution.

  • Modules/mediastream/RTCRtpSender.cpp:

(WebCore::RTCRtpSender::replaceTrack):

  • Modules/mediastream/RTCRtpSender.h:
  • Modules/mediastream/RTCRtpSender.idl:
  • Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp:

(WebCore::LibWebRTCPeerConnectionBackend::replaceTrack):

  • Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h:
  • platform/mediastream/mac/RealtimeOutgoingAudioSource.cpp:

(WebCore::RealtimeOutgoingAudioSource::setSource):

  • platform/mediastream/mac/RealtimeOutgoingAudioSource.h:
  • platform/mediastream/mac/RealtimeOutgoingVideoSource.cpp:

(WebCore::RealtimeOutgoingVideoSource::setSource):

  • platform/mediastream/mac/RealtimeOutgoingVideoSource.h:
  • platform/mock/MockRealtimeVideoSource.cpp:

(WebCore::MockRealtimeVideoSource::drawText):
(WebCore::MockRealtimeVideoSource::generateFrame):

LayoutTests:

  • webrtc/audio-replace-track-expected.txt: Added.
  • webrtc/audio-replace-track.html: Added.
  • webrtc/video-replace-track-expected.txt: Added.
  • webrtc/video-replace-track.html: Added.
  • webrtc/video-replace-track-to-null-expected.txt: Added.
  • webrtc/video-replace-track-to-null.html: Added.
Location:
trunk
Files:
6 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r214355 r214357  
     12017-03-24  Youenn Fablet  <youenn@apple.com>
     2
     3        Add libwebrtc backend support for RTCRtpSender::replaceTrack
     4        https://bugs.webkit.org/show_bug.cgi?id=169841
     5
     6        Reviewed by Alex Christensen.
     7
     8        * webrtc/audio-replace-track-expected.txt: Added.
     9        * webrtc/audio-replace-track.html: Added.
     10        * webrtc/video-replace-track-expected.txt: Added.
     11        * webrtc/video-replace-track.html: Added.
     12        * webrtc/video-replace-track-to-null-expected.txt: Added.
     13        * webrtc/video-replace-track-to-null.html: Added.
     14
    1152017-03-24  Ryan Haddad  <ryanhaddad@apple.com>
    216
  • trunk/Source/WebCore/ChangeLog

    r214356 r214357  
     12017-03-24  Youenn Fablet  <youenn@apple.com>
     2
     3        Add libwebrtc backend support for RTCRtpSender::replaceTrack
     4        https://bugs.webkit.org/show_bug.cgi?id=169841
     5
     6        Reviewed by Alex Christensen.
     7
     8        Tests: webrtc/audio-replace-track.html
     9               webrtc/video-replace-track.html
     10
     11        Adding support for replaceTrack for audio and video sources.
     12        Replacing tracks will always succeed for audio sources.
     13        For video tracks, it will only succeed if the video resolution is not greater.
     14        LibWebRTCPeerConnectionBackend will delegate the track replacing by replacing the source of the outgoing sources with the source wrapped in the replacing track.
     15
     16        Video test is not fully passing as size constraints for mock video sources are not providing the right video stream resolution.
     17
     18        * Modules/mediastream/RTCRtpSender.cpp:
     19        (WebCore::RTCRtpSender::replaceTrack):
     20        * Modules/mediastream/RTCRtpSender.h:
     21        * Modules/mediastream/RTCRtpSender.idl:
     22        * Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp:
     23        (WebCore::LibWebRTCPeerConnectionBackend::replaceTrack):
     24        * Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h:
     25        * platform/mediastream/mac/RealtimeOutgoingAudioSource.cpp:
     26        (WebCore::RealtimeOutgoingAudioSource::setSource):
     27        * platform/mediastream/mac/RealtimeOutgoingAudioSource.h:
     28        * platform/mediastream/mac/RealtimeOutgoingVideoSource.cpp:
     29        (WebCore::RealtimeOutgoingVideoSource::setSource):
     30        * platform/mediastream/mac/RealtimeOutgoingVideoSource.h:
     31        * platform/mock/MockRealtimeVideoSource.cpp:
     32        (WebCore::MockRealtimeVideoSource::drawText):
     33        (WebCore::MockRealtimeVideoSource::generateFrame):
     34
    1352017-03-24  Jon Lee  <jonlee@apple.com>
    236
  • trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp

    r214330 r214357  
    497497}
    498498
    499 void RTCPeerConnection::replaceTrack(RTCRtpSender& sender, Ref<MediaStreamTrack>&& withTrack, DOMPromise<void>&& promise)
    500 {
    501     m_backend->replaceTrack(sender, WTFMove(withTrack), WTFMove(promise));
     499void RTCPeerConnection::enqueueReplaceTrackTask(RTCRtpSender& sender, Ref<MediaStreamTrack>&& withTrack, DOMPromise<void>&& promise)
     500{
     501    scriptExecutionContext()->postTask([protectedSender = makeRef(sender), promise = WTFMove(promise), withTrack = WTFMove(withTrack)](ScriptExecutionContext&) mutable {
     502        protectedSender->setTrack(WTFMove(withTrack));
     503        promise.resolve();
     504    });
     505}
     506
     507void RTCPeerConnection::replaceTrack(RTCRtpSender& sender, RefPtr<MediaStreamTrack>&& withTrack, DOMPromise<void>&& promise)
     508{
     509    if (!withTrack) {
     510        scriptExecutionContext()->postTask([protectedSender = makeRef(sender), promise = WTFMove(promise)](ScriptExecutionContext&) mutable {
     511            protectedSender->setTrackToNull();
     512            promise.resolve();
     513        });
     514        return;
     515    }
     516   
     517    if (!sender.track()) {
     518        enqueueReplaceTrackTask(sender, withTrack.releaseNonNull(), WTFMove(promise));
     519        return;
     520    }
     521
     522    m_backend->replaceTrack(sender, withTrack.releaseNonNull(), WTFMove(promise));
    502523}
    503524
  • trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.h

    r214317 r214357  
    141141    void enableICECandidateFiltering() { m_backend->enableICECandidateFiltering(); }
    142142
     143    void enqueueReplaceTrackTask(RTCRtpSender&, Ref<MediaStreamTrack>&&, DOMPromise<void>&&);
     144
    143145private:
    144146    RTCPeerConnection(ScriptExecutionContext&);
     
    160162
    161163    // RTCRtpSenderClient
    162     void replaceTrack(RTCRtpSender&, Ref<MediaStreamTrack>&&, DOMPromise<void>&&) final;
     164    void replaceTrack(RTCRtpSender&, RefPtr<MediaStreamTrack>&&, DOMPromise<void>&&) final;
    163165
    164166    void updateConnectionState();
  • trunk/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp

    r214317 r214357  
    5858}
    5959
     60void RTCRtpSender::setTrackToNull()
     61{
     62    ASSERT(m_track);
     63    m_trackId = { };
     64    m_track = nullptr;
     65}
     66
    6067void RTCRtpSender::setTrack(Ref<MediaStreamTrack>&& track)
    6168{
    6269    ASSERT(!isStopped());
    63     ASSERT(!m_track);
    64     m_trackId = track->id();
     70    if (!m_track)
     71        m_trackId = track->id();
    6572    m_track = WTFMove(track);
    6673}
    6774
    68 ExceptionOr<void> RTCRtpSender::replaceTrack(Ref<MediaStreamTrack>&& withTrack, DOMPromise<void>&& promise)
     75void RTCRtpSender::replaceTrack(RefPtr<MediaStreamTrack>&& withTrack, DOMPromise<void>&& promise)
    6976{
    7077    if (isStopped()) {
    7178        promise.reject(INVALID_STATE_ERR);
    72         return { };
     79        return;
    7380    }
    7481
    75     if (m_trackKind != withTrack->kind())
    76         return Exception { TypeError };
     82    if (withTrack && m_trackKind != withTrack->kind()) {
     83        promise.reject(TypeError);
     84        return;
     85    }
     86
     87    if (!withTrack && m_track)
     88        m_track->stopProducingData();
    7789
    7890    m_client->replaceTrack(*this, WTFMove(withTrack), WTFMove(promise));
    79 
    80     return { };
    8191}
    8292
  • trunk/Source/WebCore/Modules/mediastream/RTCRtpSender.h

    r214317 r214357  
    4040class RTCRtpSenderClient {
    4141public:
    42     virtual void replaceTrack(RTCRtpSender&, Ref<MediaStreamTrack>&&, DOMPromise<void>&&) = 0;
     42    virtual void replaceTrack(RTCRtpSender&, RefPtr<MediaStreamTrack>&&, DOMPromise<void>&&) = 0;
    4343
    4444    virtual ~RTCRtpSenderClient() { }
     
    5959    void stop() { m_client = nullptr; }
    6060    void setTrack(Ref<MediaStreamTrack>&&);
     61    void setTrackToNull();
    6162
    62     ExceptionOr<void> replaceTrack(Ref<MediaStreamTrack>&&, DOMPromise<void>&&);
     63    void replaceTrack(RefPtr<MediaStreamTrack>&&, DOMPromise<void>&&);
    6364
    6465private:
  • trunk/Source/WebCore/Modules/mediastream/RTCRtpSender.idl

    r214045 r214357  
    4040    // FIXME 169662: missing setParameters
    4141    // FIXME 169662: missing getParameters
    42     [MayThrowException] Promise<void> replaceTrack(MediaStreamTrack withTrack);
     42    Promise<void> replaceTrack(MediaStreamTrack? withTrack);
    4343};
  • trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp

    r214209 r214357  
    2929
    3030#include "Document.h"
     31#include "ExceptionCode.h"
    3132#include "IceCandidate.h"
    3233#include "JSRTCStatsReport.h"
     
    322323}
    323324
     325void LibWebRTCPeerConnectionBackend::replaceTrack(RTCRtpSender& sender, Ref<MediaStreamTrack>&& track, DOMPromise<void>&& promise)
     326{
     327    ASSERT(sender.track());
     328    auto* currentTrack = sender.track();
     329
     330    ASSERT(currentTrack->source().type() == track->source().type());
     331    switch (currentTrack->source().type()) {
     332    case RealtimeMediaSource::Type::None:
     333        ASSERT_NOT_REACHED();
     334        promise.reject(INVALID_MODIFICATION_ERR);
     335        break;
     336    case RealtimeMediaSource::Type::Audio: {
     337        for (auto& audioSource : m_audioSources) {
     338            if (&audioSource->source() == &currentTrack->source()) {
     339                if (!audioSource->setSource(track->source())) {
     340                    promise.reject(INVALID_MODIFICATION_ERR);
     341                    return;
     342                }
     343                connection().enqueueReplaceTrackTask(sender, WTFMove(track), WTFMove(promise));
     344                return;
     345            }
     346        }
     347        promise.reject(INVALID_MODIFICATION_ERR);
     348        break;
     349    }
     350    case RealtimeMediaSource::Type::Video: {
     351        for (auto& videoSource : m_videoSources) {
     352            if (&videoSource->source() == &currentTrack->source()) {
     353                if (!videoSource->setSource(track->source())) {
     354                    promise.reject(INVALID_MODIFICATION_ERR);
     355                    return;
     356                }
     357                connection().enqueueReplaceTrackTask(sender, WTFMove(track), WTFMove(promise));
     358                return;
     359            }
     360        }
     361        promise.reject(INVALID_MODIFICATION_ERR);
     362        break;
     363    }
     364    }
     365}
     366
    324367} // namespace WebCore
    325368
  • trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h

    r214212 r214357  
    7070    RefPtr<RTCSessionDescription> pendingRemoteDescription() const final;
    7171
    72     // FIXME: API to implement for real
    73     void replaceTrack(RTCRtpSender&, Ref<MediaStreamTrack>&&, DOMPromise<void>&&) final { }
     72    void replaceTrack(RTCRtpSender&, Ref<MediaStreamTrack>&&, DOMPromise<void>&&) final;
    7473
    7574    void emulatePlatformEvent(const String&) final { }
  • trunk/Source/WebCore/platform/mediastream/mac/RealtimeOutgoingAudioSource.cpp

    r214134 r214357  
    5050{
    5151    m_audioSource->addObserver(*this);
     52}
     53
     54bool RealtimeOutgoingAudioSource::setSource(Ref<RealtimeMediaSource>&& newSource)
     55{
     56    m_audioSource->removeObserver(*this);
     57    m_audioSource = WTFMove(newSource);
     58    m_audioSource->addObserver(*this);
     59    return true;
    5260}
    5361
  • trunk/Source/WebCore/platform/mediastream/mac/RealtimeOutgoingAudioSource.h

    r214134 r214357  
    5252    void stop();
    5353
     54    bool setSource(Ref<RealtimeMediaSource>&&);
     55    RealtimeMediaSource& source() const { return m_audioSource.get(); }
     56
    5457private:
    5558    explicit RealtimeOutgoingAudioSource(Ref<RealtimeMediaSource>&&);
  • trunk/Source/WebCore/platform/mediastream/mac/RealtimeOutgoingVideoSource.cpp

    r214134 r214357  
    4545{
    4646    m_videoSource->addObserver(*this);
     47}
     48
     49bool RealtimeOutgoingVideoSource::setSource(Ref<RealtimeMediaSource>&& newSource)
     50{
     51    if (!m_initialSettings)
     52        m_initialSettings = m_videoSource->settings();
     53
     54    auto newSettings = newSource->settings();
     55
     56    if (m_initialSettings->width() < newSettings.width() || m_initialSettings->height() < newSettings.height())
     57        return false;
     58
     59    m_videoSource->removeObserver(*this);
     60    m_videoSource = WTFMove(newSource);
     61    m_videoSource->addObserver(*this);
     62    return true;
    4763}
    4864
  • trunk/Source/WebCore/platform/mediastream/mac/RealtimeOutgoingVideoSource.h

    r214134 r214357  
    3737#include <webrtc/common_video/include/i420_buffer_pool.h>
    3838#include <webrtc/media/base/videosinkinterface.h>
     39#include <wtf/Optional.h>
    3940#include <wtf/ThreadSafeRefCounted.h>
    4041
     
    4748
    4849    void stop();
     50    bool setSource(Ref<RealtimeMediaSource>&&);
     51    RealtimeMediaSource& source() const { return m_videoSource.get(); }
    4952
    5053    int AddRef() const final { ref(); return refCount(); }
     
    8386    bool m_enabled { true };
    8487    bool m_muted { false };
     88    std::optional<RealtimeMediaSourceSettings> m_initialSettings;
    8589};
    8690
  • trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp

    r214178 r214357  
    328328    unsigned frameMod = m_frameNumber % 60;
    329329    if (frameMod <= 15) {
    330         context.setFillColor(Color::gray);
     330        context.setFillColor(Color::cyan);
    331331        String bip(ASCIILiteral("Bip"));
    332332        context.drawText(m_bipBopFont, TextRun(StringView(bip)), bipBopLocation);
    333333    } else if (frameMod > 30 && frameMod <= 45) {
    334         context.setFillColor(Color::white);
     334        context.setFillColor(Color::yellow);
    335335        String bop(ASCIILiteral("Bop"));
    336336        context.drawText(m_bipBopFont, TextRun(StringView(bop)), bipBopLocation);
     
    349349    IntSize size = this->size();
    350350    FloatRect frameRect(FloatPoint(), size);
    351     context.fillRect(FloatRect(FloatPoint(), size), Color::black);
     351    context.fillRect(FloatRect(FloatPoint(), size), facingMode() ==  RealtimeMediaSourceSettings::User ? Color::black : Color::gray);
    352352
    353353    if (!m_muted && m_enabled) {
Note: See TracChangeset for help on using the changeset viewer.