Changeset 214976 in webkit


Ignore:
Timestamp:
Apr 5, 2017 4:22:20 PM (7 years ago)
Author:
eric.carlson@apple.com
Message:

[MediaStream] Host application should be able to mute and unmute media streams
https://bugs.webkit.org/show_bug.cgi?id=170519
<rdar://problem/31174326>

Reviewed by Youenn Fablet.

Source/WebCore:

No new tests, fast/mediastream/MediaStream-page-muted.html was updated.

  • Modules/mediastream/MediaStream.cpp:

(WebCore::MediaStream::~MediaStream): Fix a typo.
(WebCore::MediaStream::pageMutedStateDidChange): Don't store muted state, let the private
stream store it.
(WebCore::MediaStream::mediaState): Deal with new muted state flags.

  • Modules/mediastream/MediaStream.h:
  • dom/Document.cpp:

(WebCore::Document::prepareForDestruction): Clear media state before the frame is cleared.

  • page/MediaProducer.h: Add muted flags.
  • platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:

(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::checkSelectedVideoTrack): The display layer
should not be visible when the video track is muted.

  • platform/mediastream/MediaStreamPrivate.cpp:

(WebCore::MediaStreamPrivate::addTrack): Mute the new track if necessary.
(WebCore::MediaStreamPrivate::startProducingData): Do nothing when muted.
(WebCore::MediaStreamPrivate::setExternallyMuted): New, mute/unmute tracks.

  • platform/mediastream/MediaStreamPrivate.h:
  • platform/mediastream/RealtimeMediaSource.cpp:

(WebCore::RealtimeMediaSource::setMuted): Start/stop producing data.

  • testing/Internals.cpp:

(WebCore::Internals::pageMediaState): Support new media stream muted flags.

Source/WebKit2:

  • UIProcess/API/C/WKPage.cpp:

(WKPageGetMediaState): Support new media stream state flags.

  • UIProcess/API/C/WKPagePrivate.h:
  • UIProcess/API/Cocoa/WKWebViewPrivate.h: Ditto.
  • UIProcess/Cocoa/UIDelegate.mm: Ditto.

LayoutTests:

  • fast/mediastream/MediaStream-page-muted-expected.txt:
  • fast/mediastream/MediaStream-page-muted.html:
Location:
trunk
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r214966 r214976  
     12017-04-05  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [MediaStream] Host application should be able to mute and unmute media streams
     4        https://bugs.webkit.org/show_bug.cgi?id=170519
     5        <rdar://problem/31174326>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        * fast/mediastream/MediaStream-page-muted-expected.txt:
     10        * fast/mediastream/MediaStream-page-muted.html:
     11
    1122017-04-05  Javier Fernandez  <jfernandez@igalia.com>
    213
  • trunk/LayoutTests/fast/mediastream/MediaStream-page-muted-expected.txt

    r208778 r214976  
    1616PASS muteChangedEvent.target.muted is true
    1717
    18 PASS window.internals.pageMediaState().includes('HasActiveAudioCaptureDevice') && window.internals.pageMediaState().includes('HasActiveVideoCaptureDevice') became false
     18PASS window.internals.pageMediaState().includes(HasMutedAudioCaptureDevice) became true
     19PASS window.internals.pageMediaState().includes(HasMutedVideoCaptureDevice) became true
     20PASS window.internals.pageMediaState().includes(HasActiveAudioCaptureDevice) became false
     21PASS window.internals.pageMediaState().includes(HasActiveVideoCaptureDevice) became false
    1922
    2023*** Unmuting capture devices
     
    2427PASS muteChangedEvent.target.muted is false
    2528
    26 PASS window.internals.pageMediaState().includes('HasActiveAudioCaptureDevice') && window.internals.pageMediaState().includes('HasActiveVideoCaptureDevice') became true
     29PASS window.internals.pageMediaState().includes(HasActiveAudioCaptureDevice) became true
     30PASS window.internals.pageMediaState().includes(HasActiveVideoCaptureDevice) became true
     31PASS window.internals.pageMediaState().includes(HasMutedAudioCaptureDevice) became false
     32PASS window.internals.pageMediaState().includes(HasMutedVideoCaptureDevice) became false
    2733PASS successfullyParsed is true
    2834
  • trunk/LayoutTests/fast/mediastream/MediaStream-page-muted.html

    r208778 r214976  
    2828                if (++eventCount == 2) {
    2929                    debug("");
    30                     let shouldBeActive = muteChangedEvent.type == "mute" ? "false" : "true";
    31                     shouldBecomeEqual("window.internals.pageMediaState().includes('HasActiveAudioCaptureDevice') && window.internals.pageMediaState().includes('HasActiveVideoCaptureDevice')", shouldBeActive, nextStep);
     30                   
     31                    let activeState = muteChangedEvent.type == "mute" ? "Muted" : "Active";
     32                    let inactiveState = muteChangedEvent.type == "mute" ? "Active" : "Muted";
     33                    let retryCount = 0;
     34                    let retryInterval = 100;
     35                    let maximumRetryCount = 20 * 1000 / retryInterval;
     36                    let test = () => {
     37
     38                        if (window.internals.pageMediaState().includes(`Has${activeState}AudioCaptureDevice`)
     39                            && window.internals.pageMediaState().includes(`Has${activeState}VideoCaptureDevice`)
     40                            && !window.internals.pageMediaState().includes(`Has${inactiveState}VideoCaptureDevice`)
     41                            && !window.internals.pageMediaState().includes(`Has${inactiveState}VideoCaptureDevice`)) {
     42
     43                            testPassed(`window.internals.pageMediaState().includes(Has${activeState}AudioCaptureDevice) became true`);
     44                            testPassed(`window.internals.pageMediaState().includes(Has${activeState}VideoCaptureDevice) became true`);
     45                            testPassed(`window.internals.pageMediaState().includes(Has${inactiveState}AudioCaptureDevice) became false`);
     46                            testPassed(`window.internals.pageMediaState().includes(Has${inactiveState}VideoCaptureDevice) became false`);
     47                           
     48                            nextStep()
     49                            return;
     50                        }
     51                       
     52                        if (++retryCount > maximumRetryCount) {
     53                            testFailed(`Page muted state failed to change after ${maximumRetryCount / 1000} seconds`);
     54                            return;
     55                        }
     56                       
     57                        setTimeout(test, retryInterval);
     58                    }
     59
     60                    setTimeout(test, 0);
    3261                }
    3362            }
  • trunk/Source/WebCore/ChangeLog

    r214974 r214976  
     12017-04-05  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [MediaStream] Host application should be able to mute and unmute media streams
     4        https://bugs.webkit.org/show_bug.cgi?id=170519
     5        <rdar://problem/31174326>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        No new tests, fast/mediastream/MediaStream-page-muted.html was updated.
     10
     11        * Modules/mediastream/MediaStream.cpp:
     12        (WebCore::MediaStream::~MediaStream): Fix a typo.
     13        (WebCore::MediaStream::pageMutedStateDidChange): Don't store muted state, let the private
     14        stream store it.
     15        (WebCore::MediaStream::mediaState): Deal with new muted state flags.
     16        * Modules/mediastream/MediaStream.h:
     17
     18        * dom/Document.cpp:
     19        (WebCore::Document::prepareForDestruction): Clear media state before the frame is cleared.
     20
     21        * page/MediaProducer.h: Add muted flags.
     22
     23        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
     24        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::checkSelectedVideoTrack): The display layer
     25        should not be visible when the video track is muted.
     26
     27        * platform/mediastream/MediaStreamPrivate.cpp:
     28        (WebCore::MediaStreamPrivate::addTrack): Mute the new track if necessary.
     29        (WebCore::MediaStreamPrivate::startProducingData): Do nothing when muted.
     30        (WebCore::MediaStreamPrivate::setExternallyMuted): New, mute/unmute tracks.
     31        * platform/mediastream/MediaStreamPrivate.h:
     32
     33        * platform/mediastream/RealtimeMediaSource.cpp:
     34        (WebCore::RealtimeMediaSource::setMuted): Start/stop producing data.
     35
     36        * testing/Internals.cpp:
     37        (WebCore::Internals::pageMediaState): Support new media stream muted flags.
     38
    1392017-04-05  Andreas Kling  <akling@apple.com>
    240
  • trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp

    r214132 r214976  
    105105MediaStream::~MediaStream()
    106106{
    107     // Set isActive to false immediately so an callbacks triggered by shutting down, e.g.
     107    // Set isActive to false immediately so any callbacks triggered by shutting down, e.g.
    108108    // mediaState(), are short circuited.
    109109    m_isActive = false;
     
    301301        return;
    302302
    303     bool pageMuted = document->page()->isMediaCaptureMuted();
    304     if (m_externallyMuted == pageMuted)
    305         return;
    306 
    307     m_externallyMuted = pageMuted;
    308     if (pageMuted)
    309         stopProducingData();
    310     else
    311         startProducingData();
     303    m_private->setMuted(document->page()->isMediaCaptureMuted());
    312304}
    313305
     
    321313    if (m_private->hasAudio()) {
    322314        state |= HasAudioOrVideo;
    323         if (m_private->hasCaptureAudioSource() && m_private->isProducingData())
    324             state |= HasActiveAudioCaptureDevice;
     315        if (m_private->hasCaptureAudioSource()) {
     316            if (m_private->isProducingData())
     317                state |= HasActiveAudioCaptureDevice;
     318            else if (m_private->muted())
     319                state |= HasMutedAudioCaptureDevice;
     320        }
    325321    }
    326322
    327323    if (m_private->hasVideo()) {
    328324        state |= HasAudioOrVideo;
    329         if (m_private->hasCaptureVideoSource() && m_private->isProducingData())
    330             state |= HasActiveVideoCaptureDevice;
     325        if (m_private->hasCaptureVideoSource()) {
     326            if (m_private->isProducingData())
     327                state |= HasActiveVideoCaptureDevice;
     328            else if (m_private->muted())
     329                state |= HasMutedVideoCaptureDevice;
     330        }
    331331    }
    332332
  • trunk/Source/WebCore/Modules/mediastream/MediaStream.h

    r214132 r214976  
    158158    bool m_isActive { false };
    159159    bool m_isMuted { true };
    160     bool m_externallyMuted { false };
    161160    bool m_isWaitingUntilMediaCanStart { false };
    162161};
  • trunk/Source/WebCore/dom/Document.cpp

    r214900 r214976  
    22682268    m_cachedResourceLoader->stopUnusedPreloadsTimer();
    22692269
     2270    if (page() && m_mediaState != MediaProducer::IsNotPlaying) {
     2271        m_mediaState = MediaProducer::IsNotPlaying;
     2272        page()->updateIsPlayingMedia(HTMLMediaElementInvalidID);
     2273    }
     2274
    22702275    detachFromFrame();
    22712276
  • trunk/Source/WebCore/page/MediaProducer.h

    r208778 r214976  
    4545        HasActiveAudioCaptureDevice = 1 << 11,
    4646        HasActiveVideoCaptureDevice = 1 << 12,
     47        HasMutedAudioCaptureDevice = 1 << 13,
     48        HasMutedVideoCaptureDevice = 1 << 14,
    4749    };
    4850    typedef unsigned MediaStateFlags;
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm

    r214953 r214976  
    951951            m_imagePainter.reset();
    952952        ensureLayers();
    953         m_sampleBufferDisplayLayer.get().hidden = hideVideoLayer;
     953        m_sampleBufferDisplayLayer.get().hidden = hideVideoLayer || m_displayMode < PausedImage;
    954954        m_pendingSelectedTrackCheck = false;
    955955        updateDisplayMode();
  • trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp

    r214042 r214976  
    135135        return;
    136136
     137    if (m_muted)
     138        track->stopProducingData();
     139
    137140    track->addObserver(*this);
    138141    m_trackSet.add(track->id(), track);
     
    163166void MediaStreamPrivate::startProducingData()
    164167{
     168    if (m_muted)
     169        return;
     170
    165171    for (auto& track : m_trackSet.values())
    166172        track->startProducingData();
     
    180186    }
    181187    return false;
     188}
     189
     190void MediaStreamPrivate::setMuted(bool muted)
     191{
     192    if (m_muted == muted)
     193        return;
     194
     195    m_muted = muted;
     196    for (auto& track : m_trackSet.values()) {
     197        if (track->isCaptureTrack())
     198            track->setMuted(muted);
     199    }
    182200}
    183201
  • trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.h

    r214042 r214976  
    9696    bool hasVideo() const;
    9797    bool hasAudio() const;
     98
     99    void setMuted(bool);
    98100    bool muted() const;
    99101
     
    135137    HashMap<String, RefPtr<MediaStreamTrackPrivate>> m_trackSet;
    136138    bool m_isActive { false };
     139    bool m_muted { false };
    137140};
    138141
  • trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp

    r214385 r214976  
    9292        return;
    9393
     94    if (muted) {
     95        // FIXME: We need to figure out how to guarantee that at least one black video frame is
     96        // emitted after being muted.
     97        stopProducingData();
     98    } else
     99        startProducingData();
     100
    94101    for (auto& observer : m_observers)
    95102        observer->sourceMutedChanged();
  • trunk/Source/WebCore/testing/Internals.cpp

    r214913 r214976  
    35243524    if (state & MediaProducer::HasActiveVideoCaptureDevice)
    35253525        string.append("HasActiveVideoCaptureDevice,");
     3526    if (state & MediaProducer::HasMutedAudioCaptureDevice)
     3527        string.append("HasMutedAudioCaptureDevice,");
     3528    if (state & MediaProducer::HasMutedVideoCaptureDevice)
     3529        string.append("HasMutedVideoCaptureDevice,");
    35263530
    35273531    if (string.isEmpty())
  • trunk/Source/WebKit2/ChangeLog

    r214973 r214976  
     12017-04-05  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [MediaStream] Host application should be able to mute and unmute media streams
     4        https://bugs.webkit.org/show_bug.cgi?id=170519
     5        <rdar://problem/31174326>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        * UIProcess/API/C/WKPage.cpp:
     10        (WKPageGetMediaState): Support new media stream state flags.
     11        * UIProcess/API/C/WKPagePrivate.h:
     12        * UIProcess/API/Cocoa/WKWebViewPrivate.h: Ditto.
     13        * UIProcess/Cocoa/UIDelegate.mm: Ditto.
     14
    1152017-04-05  Brady Eidson  <beidson@apple.com>
    216
  • trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp

    r214893 r214976  
    28142814    if (coreState & WebCore::MediaProducer::HasActiveVideoCaptureDevice)
    28152815        state |= kWKMediaHasActiveVideoCaptureDevice;
     2816    if (coreState & WebCore::MediaProducer::HasMutedAudioCaptureDevice)
     2817        state |= kWKMediaHasMutedAudioCaptureDevice;
     2818    if (coreState & WebCore::MediaProducer::HasMutedVideoCaptureDevice)
     2819        state |= kWKMediaHasMutedVideoCaptureDevice;
    28162820
    28172821    return state;
  • trunk/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h

    r212534 r214976  
    138138    kWKMediaHasActiveAudioCaptureDevice = 1 << 2,
    139139    kWKMediaHasActiveVideoCaptureDevice = 1 << 3,
     140    kWKMediaHasMutedAudioCaptureDevice = 1 << 4,
     141    kWKMediaHasMutedVideoCaptureDevice = 1 << 5,
    140142};
    141143typedef uint32_t WKMediaState;
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h

    r214643 r214976  
    4242typedef NS_OPTIONS(NSInteger, _WKMediaCaptureState) {
    4343    _WKMediaCaptureStateNone = 0,
    44     _WKMediaCaptureStateMicrophone = 1 << 0,
    45     _WKMediaCaptureStateCamera = 1 << 1,
     44    _WKMediaCaptureStateActiveMicrophone = 1 << 0,
     45    _WKMediaCaptureStateActiveCamera = 1 << 1,
     46    _WKMediaCaptureStateMutedMicrophone = 1 << 2,
     47    _WKMediaCaptureStateMutedCamera = 1 << 3,
    4648} WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
    4749
  • trunk/Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm

    r213683 r214976  
    444444    _WKMediaCaptureState mediaCaptureState = _WKMediaCaptureStateNone;
    445445    if (state & WebCore::MediaProducer::HasActiveAudioCaptureDevice)
    446         mediaCaptureState |= _WKMediaCaptureStateMicrophone;
     446        mediaCaptureState |= _WKMediaCaptureStateActiveMicrophone;
    447447    if (state & WebCore::MediaProducer::HasActiveVideoCaptureDevice)
    448         mediaCaptureState |= _WKMediaCaptureStateCamera;
     448        mediaCaptureState |= _WKMediaCaptureStateActiveCamera;
     449    if (state & WebCore::MediaProducer::HasActiveAudioCaptureDevice)
     450        mediaCaptureState |= _WKMediaCaptureStateMutedMicrophone;
     451    if (state & WebCore::MediaProducer::HasMutedVideoCaptureDevice)
     452        mediaCaptureState |= _WKMediaCaptureStateMutedCamera;
    449453
    450454    [(id <WKUIDelegatePrivate>)delegate _webView:webView mediaCaptureStateDidChange:mediaCaptureState];
Note: See TracChangeset for help on using the changeset viewer.