MediaPlayerPrivateMediaStreamAVFObjC should start play a newly added audio track...
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 20 Apr 2020 18:16:57 +0000 (18:16 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 20 Apr 2020 18:16:57 +0000 (18:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=210740

Reviewed by Eric Carlson.

Source/WebCore:

Before the patch, MediaPlayerPrivateMediaStreamAVFObjC was not calling play on the audio renderer when the audio renderer
was added after the MediaPlayerPrivateMediaStreamAVFObjC was asked to play.
This patch makes it so that, on configuration of an audio track, it will be asked to play if its MediaPlayerPrivateMediaStreamAVFObjC is playing.
Add internals API to be able to write a test.

Test: fast/mediastream/play-newly-added-audio-track.html

* html/track/AudioTrack.h:
* html/track/AudioTrack.idl:
* platform/graphics/AudioTrackPrivate.h:
(WebCore::AudioTrackPrivate::isBackedByMediaStreamTrack const):
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::updateTracks):
* platform/mediastream/AudioTrackPrivateMediaStream.cpp:
(WebCore::AudioTrackPrivateMediaStream::play):
* platform/mediastream/AudioTrackPrivateMediaStream.h:
(isType):
* testing/Internals.cpp:
(WebCore::Internals::isMockRealtimeMediaSourceCenterEnabled):
(WebCore::Internals::shouldAudioTrackPlay):
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

* fast/mediastream/play-newly-added-audio-track-expected.txt: Added.
* fast/mediastream/play-newly-added-audio-track.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260380 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/mediastream/play-newly-added-audio-track-expected.txt [new file with mode: 0644]
LayoutTests/fast/mediastream/play-newly-added-audio-track.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/html/track/AudioTrack.h
Source/WebCore/html/track/AudioTrack.idl
Source/WebCore/platform/graphics/AudioTrackPrivate.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm
Source/WebCore/platform/mediastream/AudioTrackPrivateMediaStream.cpp
Source/WebCore/platform/mediastream/AudioTrackPrivateMediaStream.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl

index 532f499..ac994a4 100644 (file)
@@ -1,3 +1,13 @@
+2020-04-20  Youenn Fablet  <youenn@apple.com>
+
+        MediaPlayerPrivateMediaStreamAVFObjC should start play a newly added audio track if it is playing
+        https://bugs.webkit.org/show_bug.cgi?id=210740
+
+        Reviewed by Eric Carlson.
+
+        * fast/mediastream/play-newly-added-audio-track-expected.txt: Added.
+        * fast/mediastream/play-newly-added-audio-track.html: Added.
+
 2020-04-20  Zalan Bujtas  <zalan@apple.com>
 
         fast/layoutformattingcontext/simple-absolute-positioned-replaced-inline-element-with-percentage-height.html is flaky
diff --git a/LayoutTests/fast/mediastream/play-newly-added-audio-track-expected.txt b/LayoutTests/fast/mediastream/play-newly-added-audio-track-expected.txt
new file mode 100644 (file)
index 0000000..7cafd17
--- /dev/null
@@ -0,0 +1,5 @@
+
+
+PASS Add an audio track while playing video 
+PASS Add an audio track while playing audio 
+
diff --git a/LayoutTests/fast/mediastream/play-newly-added-audio-track.html b/LayoutTests/fast/mediastream/play-newly-added-audio-track.html
new file mode 100644 (file)
index 0000000..7fe9e2a
--- /dev/null
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <video id="video" autoplay controls></video>
+        <script src="../../resources/testharness.js"></script>
+        <script src="../../resources/testharnessreport.js"></script>
+        <script>
+promise_test(async () => {
+    let stream = await navigator.mediaDevices.getUserMedia({ video : true });
+    video.srcObject = stream;
+
+    await video.play();
+
+    let stream2 = await navigator.mediaDevices.getUserMedia({ audio : true });
+    video.srcObject.addTrack(stream2.getAudioTracks()[0]);
+
+    if (window.internals)
+        assert_true(internals.shouldAudioTrackPlay(video.audioTracks[0]));
+}, "Add an audio track while playing video");
+
+promise_test(async () => {
+    let stream = await navigator.mediaDevices.getUserMedia({ audio : true });
+    video.srcObject = stream.clone();
+
+    await video.play();
+
+    video.srcObject.addTrack(stream.getAudioTracks()[0]);
+    await new Promise(resolve => setTimeout(resolve, 50));
+    if (window.internals)
+        assert_true(internals.shouldAudioTrackPlay(video.audioTracks[1]));
+}, "Add an audio track while playing audio");
+        </script>
+    </head>
+</html>
index 92039c8..ec102c0 100644 (file)
@@ -1,5 +1,35 @@
 2020-04-20  Youenn Fablet  <youenn@apple.com>
 
+        MediaPlayerPrivateMediaStreamAVFObjC should start play a newly added audio track if it is playing
+        https://bugs.webkit.org/show_bug.cgi?id=210740
+
+        Reviewed by Eric Carlson.
+
+        Before the patch, MediaPlayerPrivateMediaStreamAVFObjC was not calling play on the audio renderer when the audio renderer
+        was added after the MediaPlayerPrivateMediaStreamAVFObjC was asked to play.
+        This patch makes it so that, on configuration of an audio track, it will be asked to play if its MediaPlayerPrivateMediaStreamAVFObjC is playing.
+        Add internals API to be able to write a test.
+
+        Test: fast/mediastream/play-newly-added-audio-track.html
+
+        * html/track/AudioTrack.h:
+        * html/track/AudioTrack.idl:
+        * platform/graphics/AudioTrackPrivate.h:
+        (WebCore::AudioTrackPrivate::isBackedByMediaStreamTrack const):
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::updateTracks):
+        * platform/mediastream/AudioTrackPrivateMediaStream.cpp:
+        (WebCore::AudioTrackPrivateMediaStream::play):
+        * platform/mediastream/AudioTrackPrivateMediaStream.h:
+        (isType):
+        * testing/Internals.cpp:
+        (WebCore::Internals::isMockRealtimeMediaSourceCenterEnabled):
+        (WebCore::Internals::shouldAudioTrackPlay):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
+2020-04-20  Youenn Fablet  <youenn@apple.com>
+
         Use a WeakHashSet to store MediaStreamPrivate observers
         https://bugs.webkit.org/show_bug.cgi?id=210494
 
index ee241e3..a9a956c 100644 (file)
@@ -64,7 +64,9 @@ public:
 
     size_t inbandTrackIndex() const;
 
+    const AudioTrackPrivate& privateTrack() const { return m_private; }
     void setPrivate(AudioTrackPrivate&);
+
     void setMediaElement(WeakPtr<HTMLMediaElement>) override;
 #if !RELEASE_LOG_DISABLED
     void setLogger(const Logger&, const void*) final;
index cb26748..dcdb7a6 100644 (file)
@@ -25,6 +25,7 @@
 
 [
     Conditional=VIDEO_TRACK,
+    ExportMacro=WEBCORE_EXPORT,
     GenerateIsReachable=ImplElementRoot,
     JSCustomMarkFunction
 ] interface AudioTrack {
index 621ba86..f927864 100644 (file)
@@ -62,6 +62,8 @@ public:
     enum Kind { Alternative, Description, Main, MainDesc, Translation, Commentary, None };
     virtual Kind kind() const { return None; }
 
+    virtual bool isBackedByMediaStreamTrack() const { return false; }
+
 #if !RELEASE_LOG_DISABLED
     const char* logClassName() const override { return "AudioTrackPrivate"; }
 #endif
index 438bb9a..bb5efa6 100644 (file)
@@ -895,8 +895,11 @@ void MediaPlayerPrivateMediaStreamAVFObjC::updateTracks()
             break;
         case TrackState::Configure:
             track.setTrackIndex(index);
-            bool enabled = track.streamTrack().enabled() && !track.streamTrack().muted();
-            track.setEnabled(enabled);
+            track.setVolume(m_volume);
+            track.setMuted(m_muted);
+            track.setEnabled(track.streamTrack().enabled() && !track.streamTrack().muted());
+            if (playing())
+                track.play();
             break;
         }
     };
index 238d205..0355140 100644 (file)
@@ -72,6 +72,9 @@ void AudioTrackPrivateMediaStream::clear()
 
 void AudioTrackPrivateMediaStream::play()
 {
+    if (m_shouldPlay)
+        return;
+
     m_shouldPlay = true;
     updateRenderer();
 }
index 8ade25c..098420b 100644 (file)
@@ -54,7 +54,8 @@ public:
 
     void play();
     void pause();
-    bool isPlaying() { return m_isPlaying; }
+    bool isPlaying() const { return m_isPlaying; }
+    bool shouldPlay() const { return m_shouldPlay; }
 
     void setVolume(float);
     float volume() const;
@@ -75,6 +76,7 @@ protected:
     AtomString id() const final { return m_id; }
     AtomString label() const final { return m_label; }
     int trackIndex() const final { return m_index; }
+    bool isBackedByMediaStreamTrack() const final { return true; }
 
     // MediaStreamTrackPrivate::Observer
     void trackEnded(MediaStreamTrackPrivate&) final;
@@ -107,4 +109,8 @@ protected:
 
 }
 
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::AudioTrackPrivateMediaStream)
+    static bool isType(const WebCore::AudioTrackPrivate& track) { return track.isBackedByMediaStreamTrack(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
 #endif // ENABLE(VIDEO_TRACK) && ENABLE(MEDIA_STREAM)
index cb1e5b7..3b98d2b 100644 (file)
@@ -32,6 +32,7 @@
 #include "AnimationTimeline.h"
 #include "ApplicationCacheStorage.h"
 #include "AudioSession.h"
+#include "AudioTrackPrivateMediaStream.h"
 #include "Autofill.h"
 #include "BackForwardCache.h"
 #include "BackForwardController.h"
@@ -5076,6 +5077,13 @@ bool Internals::isMockRealtimeMediaSourceCenterEnabled()
 {
     return MockRealtimeMediaSourceCenter::mockRealtimeMediaSourceCenterEnabled();
 }
+
+bool Internals::shouldAudioTrackPlay(const AudioTrack& track)
+{
+    if (!is<AudioTrackPrivateMediaStream>(track.privateTrack()))
+        return false;
+    return downcast<AudioTrackPrivateMediaStream>(track.privateTrack()).shouldPlay();
+}
 #endif
 
 bool Internals::supportsAudioSession() const
index 91b1826..18308c5 100644 (file)
@@ -52,6 +52,7 @@ namespace WebCore {
 
 class AnimationTimeline;
 class AudioContext;
+class AudioTrack;
 class CacheStorageConnection;
 class DOMRect;
 class DOMRectList;
@@ -764,6 +765,7 @@ public:
     void setMediaStreamTrackIdentifier(MediaStreamTrack&, String&& id);
     void setMediaStreamSourceInterrupted(MediaStreamTrack&, bool);
     bool isMockRealtimeMediaSourceCenterEnabled();
+    bool shouldAudioTrackPlay(const AudioTrack&);
 #endif
 
     bool supportsAudioSession() const;
index 00ca995..3d4b925 100644 (file)
@@ -777,6 +777,7 @@ enum CompositingPolicy {
     [Conditional=MEDIA_STREAM] void setMediaStreamTrackIdentifier(MediaStreamTrack track, DOMString identifier);
     [Conditional=MEDIA_STREAM] void setMediaStreamSourceInterrupted(MediaStreamTrack track, boolean interrupted);
     [Conditional=MEDIA_STREAM] boolean isMockRealtimeMediaSourceCenterEnabled();
+    [Conditional=MEDIA_STREAM] boolean shouldAudioTrackPlay(AudioTrack track);
 
     unsigned long long documentIdentifier(Document document);
     boolean isDocumentAlive(unsigned long long documentIdentifier);