Title: [258503] trunk
Revision
258503
Author
[email protected]
Date
2020-03-16 09:36:37 -0700 (Mon, 16 Mar 2020)

Log Message

Audio is not played from an audio element when the srcObject object has unstarted video tracks
https://bugs.webkit.org/show_bug.cgi?id=207041
<rdar://problem/59084745>

Reviewed by Eric Carlson.

Source/WebCore:

In case MediaPlayer is an audio element, we should just make it as if there is no video track in the stream.

Test: imported/w3c/web-platform-tests/webrtc/audio-video-element-playing.html

* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSample):
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::ensureLayers):
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::activeVideoTrack const):
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::didPassCORSAccessCheck const):
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::currentDisplayMode const):
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::currentReadyState):
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::checkSelectedVideoTrack):
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::updateTracks):

LayoutTests:

* webrtc/audio-video-element-playing-expected.txt: Added.
* webrtc/audio-video-element-playing.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (258502 => 258503)


--- trunk/LayoutTests/ChangeLog	2020-03-16 16:34:57 UTC (rev 258502)
+++ trunk/LayoutTests/ChangeLog	2020-03-16 16:36:37 UTC (rev 258503)
@@ -1,3 +1,14 @@
+2020-03-16  youenn fablet  <[email protected]>
+
+        Audio is not played from an audio element when the srcObject object has unstarted video tracks
+        https://bugs.webkit.org/show_bug.cgi?id=207041
+        <rdar://problem/59084745>
+
+        Reviewed by Eric Carlson.
+
+        * webrtc/audio-video-element-playing-expected.txt: Added.
+        * webrtc/audio-video-element-playing.html: Added.
+
 2020-03-16  Truitt Savell  <[email protected]>
 
         [ Mac wk2 ] (r258249) fast/scrolling/mac/absolute-in-overflow-scroll-dynamic.html is a flaky failure (209052)

Added: trunk/LayoutTests/webrtc/audio-video-element-playing-expected.txt (0 => 258503)


--- trunk/LayoutTests/webrtc/audio-video-element-playing-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/webrtc/audio-video-element-playing-expected.txt	2020-03-16 16:36:37 UTC (rev 258503)
@@ -0,0 +1,4 @@
+  
+
+PASS Verify that, contrary to video elements, audio elements are playing even if video tracks have not started generated any video frame 
+

Added: trunk/LayoutTests/webrtc/audio-video-element-playing.html (0 => 258503)


--- trunk/LayoutTests/webrtc/audio-video-element-playing.html	                        (rev 0)
+++ trunk/LayoutTests/webrtc/audio-video-element-playing.html	2020-03-16 16:36:37 UTC (rev 258503)
@@ -0,0 +1,56 @@
+<!doctype html>
+<html>
+    <head>
+        <meta charset="utf-8">
+        <title>Testing audio/video element playing</title>
+        <script src=""
+        <script src=""
+    </head>
+    <body>
+        <audio id="audio" controls autoplay=""></audio>
+        <video id="video" controls autoplay=""></video>
+        <script>
+promise_test(async (t) => {
+    const pc1 = new RTCPeerConnection();
+    const pc2 = new RTCPeerConnection();
+    t.add_cleanup(() => {
+        pc1.close();
+        pc2.close();
+    });
+
+    const localStream = await navigator.mediaDevices.getUserMedia({ audio : true });
+    pc1.addTrack(localStream.getAudioTracks()[0], localStream);
+    pc1.addTransceiver("video", { streams : [localStream] });
+
+    let promise = new Promise(resolve => pc2._ontrack_ = resolve);
+
+    const offer = await pc1.createOffer();
+    await pc1.setLocalDescription(offer);
+
+    await pc2.setRemoteDescription(offer);
+    const answer = await pc2.createAnswer();
+    await pc2.setLocalDescription(answer);
+
+    await pc1.setRemoteDescription(answer);
+
+    // We do not pass any ICE candidate 
+    let remoteTrackEvent = await promise;
+
+    let remoteStream = new MediaStream([remoteTrackEvent.streams[0].getVideoTracks()[0], localStream.getAudioTracks()[0]]);
+    audio.srcObject = remoteStream;
+    video.srcObject = remoteStream;
+
+    audio.play();
+    video.play();
+
+    let counter = 0;
+    do {
+        await new Promise(resolve => t.step_timeout(resolve, 100));
+    } while (audio.currentTime === 0 && ++counter < 20)
+
+   assert_not_equals(audio.currentTime, 0);
+   assert_equals(video.currentTime, 0);
+}, "Verify that, contrary to video elements, audio elements are playing even if video tracks have not started generated any video frame");
+        </script>
+    </body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (258502 => 258503)


--- trunk/Source/WebCore/ChangeLog	2020-03-16 16:34:57 UTC (rev 258502)
+++ trunk/Source/WebCore/ChangeLog	2020-03-16 16:36:37 UTC (rev 258503)
@@ -1,5 +1,28 @@
 2020-03-16  youenn fablet  <[email protected]>
 
+        Audio is not played from an audio element when the srcObject object has unstarted video tracks
+        https://bugs.webkit.org/show_bug.cgi?id=207041
+        <rdar://problem/59084745>
+
+        Reviewed by Eric Carlson.
+
+        In case MediaPlayer is an audio element, we should just make it as if there is no video track in the stream.
+
+        Test: imported/w3c/web-platform-tests/webrtc/audio-video-element-playing.html
+
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSample):
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::ensureLayers):
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::activeVideoTrack const):
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::didPassCORSAccessCheck const):
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::currentDisplayMode const):
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::currentReadyState):
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::checkSelectedVideoTrack):
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::updateTracks):
+
+2020-03-16  youenn fablet  <[email protected]>
+
         RTCRtpSender of kind video should have a null dtmf attribute
         https://bugs.webkit.org/show_bug.cgi?id=209135
 

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h (258502 => 258503)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h	2020-03-16 16:34:57 UTC (rev 258502)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h	2020-03-16 16:36:37 UTC (rev 258503)
@@ -209,8 +209,10 @@
 
     void applicationDidBecomeActive() final;
 
-    bool hideRootLayer() const { return (!m_activeVideoTrack || m_waitingForFirstImage) && m_displayMode != PaintItBlack; }
+    bool hideRootLayer() const { return (!activeVideoTrack() || m_waitingForFirstImage) && m_displayMode != PaintItBlack; }
 
+    MediaStreamTrackPrivate* activeVideoTrack() const;
+
     MediaPlayer* m_player { nullptr };
     RefPtr<MediaStreamPrivate> m_mediaStreamPrivate;
     RefPtr<MediaStreamTrackPrivate> m_activeVideoTrack;

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm (258502 => 258503)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm	2020-03-16 16:34:57 UTC (rev 258502)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm	2020-03-16 16:36:37 UTC (rev 258503)
@@ -278,7 +278,7 @@
 
 void MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSample(MediaStreamTrackPrivate& track, MediaSample& sample)
 {
-    if (&track != m_mediaStreamPrivate->activeVideoTrack())
+    if (&track != activeVideoTrack())
         return;
 
     if (!m_imagePainter.mediaSample || m_displayMode != PausedImage) {
@@ -360,7 +360,8 @@
     if (m_sampleBufferDisplayLayer)
         return;
 
-    if (!m_mediaStreamPrivate || !m_mediaStreamPrivate->activeVideoTrack() || !m_mediaStreamPrivate->activeVideoTrack()->enabled())
+    auto* activeVideoTrack = this->activeVideoTrack();
+    if (!activeVideoTrack || !activeVideoTrack->enabled())
         return;
 
     m_sampleBufferDisplayLayer = SampleBufferDisplayLayer::create(*this);
@@ -432,11 +433,16 @@
     });
 }
 
+MediaStreamTrackPrivate* MediaPlayerPrivateMediaStreamAVFObjC::activeVideoTrack() const
+{
+    return (m_mediaStreamPrivate && m_player->isVideoPlayer()) ? m_mediaStreamPrivate->activeVideoTrack() : nullptr;
+}
+
 bool MediaPlayerPrivateMediaStreamAVFObjC::didPassCORSAccessCheck() const
 {
     // We are only doing a check on the active video track since the sole consumer of this API is canvas.
     // FIXME: We should change the name of didPassCORSAccessCheck if it is expected to stay like this.
-    const auto* track = m_mediaStreamPrivate->activeVideoTrack();
+    const auto* track = activeVideoTrack();
     return !track || !track->isIsolated();
 }
 
@@ -465,7 +471,7 @@
     if (m_intrinsicSize.isEmpty() || !metaDataAvailable() || !m_sampleBufferDisplayLayer)
         return None;
 
-    if (auto* track = m_mediaStreamPrivate->activeVideoTrack()) {
+    if (auto* track = activeVideoTrack()) {
         if (!track->enabled() || track->muted() || track->ended())
             return PaintItBlack;
     }
@@ -627,7 +633,7 @@
     if (!m_mediaStreamPrivate || !m_mediaStreamPrivate->active() || !m_mediaStreamPrivate->hasTracks())
         return MediaPlayer::ReadyState::HaveNothing;
 
-    bool waitingForImage = m_mediaStreamPrivate->activeVideoTrack() && !m_imagePainter.mediaSample;
+    bool waitingForImage = activeVideoTrack() && !m_imagePainter.mediaSample;
     if (waitingForImage && (!m_haveSeenMetadata || m_waitingForFirstImage))
         return MediaPlayer::ReadyState::HaveNothing;
 
@@ -843,10 +849,10 @@
         auto oldVideoTrack = m_activeVideoTrack;
         bool hideVideoLayer = true;
         m_activeVideoTrack = nullptr;
-        if (m_mediaStreamPrivate->activeVideoTrack()) {
+        if (auto* activeVideoTrack = this->activeVideoTrack()) {
             for (const auto& track : m_videoTrackMap.values()) {
-                if (&track->streamTrack() == m_mediaStreamPrivate->activeVideoTrack()) {
-                    m_activeVideoTrack = m_mediaStreamPrivate->activeVideoTrack();
+                if (&track->streamTrack() == activeVideoTrack) {
+                    m_activeVideoTrack = activeVideoTrack;
                     if (track->selected())
                         hideVideoLayer = false;
                     break;
@@ -896,6 +902,9 @@
     };
     updateTracksOfType(m_audioTrackMap, RealtimeMediaSource::Type::Audio, currentTracks, &AudioTrackPrivateMediaStream::create, WTFMove(setAudioTrackState));
 
+    if (!m_player->isVideoPlayer())
+        return;
+
     auto setVideoTrackState = [this](VideoTrackPrivateMediaStream& track, int index, TrackState state)
     {
         switch (state) {
@@ -910,7 +919,7 @@
             break;
         case TrackState::Configure:
             track.setTrackIndex(index);
-            bool selected = &track.streamTrack() == m_mediaStreamPrivate->activeVideoTrack();
+            bool selected = &track.streamTrack() == activeVideoTrack();
             track.setSelected(selected);
             checkSelectedVideoTrack();
             break;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to