Changeset 261553 in webkit
- Timestamp:
- May 12, 2020 4:45:25 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 33 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/imported/w3c/ChangeLog
r261488 r261553 1 2020-05-12 Youenn Fablet <youenn@apple.com> 2 3 Introduce a RealtimeMediaSource video sample observer 4 https://bugs.webkit.org/show_bug.cgi?id=211718 5 6 Reviewed by Eric Carlson. 7 8 * web-platform-tests/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https-expected.txt: 9 Drive-by fix, since we are now receiving samples but not rendering them when track is not enabled, the loadeddata event is fired appropriately. 10 Update MediaPlayerPrivateMediaStreamAVFObjC::currentDisplayMode to return PaintItBlack in that case. 11 1 12 2020-05-11 Antoine Quint <graouts@apple.com> 2 13 -
trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https-expected.txt
r252335 r261553 7 7 8 8 9 Harness Error (TIMEOUT), message = null 9 PASS Tests that a disabled video track in a MediaStream is rendered as blackness 10 10 11 TIMEOUT Tests that a disabled video track in a MediaStream is rendered as blackness Test timed out12 -
trunk/Source/WebCore/ChangeLog
r261550 r261553 1 2020-05-12 Youenn Fablet <youenn@apple.com> 2 3 Introduce a RealtimeMediaSource video sample observer 4 https://bugs.webkit.org/show_bug.cgi?id=211718 5 6 Reviewed by Eric Carlson. 7 8 We introduce an observer dedicated to video samples similarly to AudioSampleObserver for audio. 9 This will allow to move video frame processing out of the main thread progressively. 10 For now, we remove video sample observing from the track private and observers should now register directly to the realtime media source. 11 We update the various users, including MediaRecorder and the media player. 12 In both cases, they will only observe the video track to be played/recorded, which is both more efficient and simpler. 13 14 We introduced RealtimeMediaSource::Observer::hasStartedProducingData callback for MediaStreamTrackPrivate so 15 that the processing to do when the first samples are available can be done on the main thread. 16 17 MediaStreamTrackPrivate no longer filters out samples if it is not enabled. 18 As such, each consumer is now responsible to observe/unobserve the source when its track gets enabled/disabled similarly as for audio, 19 or do nothing if track is not enabled. 20 21 Similarly, RealtimeOutgoingVideoSourceCocoa will now only observe video samples when the track is enabled and not muted. 22 23 Covered by existing tests. 24 25 * Modules/mediarecorder/MediaRecorder.cpp: 26 (WebCore::MediaRecorder::sampleBufferUpdated): Deleted. 27 * Modules/mediarecorder/MediaRecorder.h: 28 * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h: 29 * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm: 30 (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::~MediaPlayerPrivateMediaStreamAVFObjC): 31 (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSample): 32 We can renove the track check since we only observe the active video track. 33 (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::videoSampleAvailable): 34 (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::checkSelectedVideoTrack): 35 (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::sampleBufferUpdated): Deleted. 36 * platform/mediarecorder/MediaRecorderPrivate.h: 37 (WebCore::MediaRecorderPrivate::setVideoSource): 38 (WebCore::MediaRecorderPrivate::~MediaRecorderPrivate): 39 * platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp: 40 (WebCore::MediaRecorderPrivateAVFImpl::create): 41 (WebCore::MediaRecorderPrivateAVFImpl::~MediaRecorderPrivateAVFImpl): 42 (WebCore::MediaRecorderPrivateAVFImpl::videoSampleAvailable): 43 (WebCore::MediaRecorderPrivateAVFImpl::stopRecording): 44 (WebCore::MediaRecorderPrivateAVFImpl::sampleBufferUpdated): Deleted. 45 * platform/mediarecorder/MediaRecorderPrivateAVFImpl.h: 46 * platform/mediarecorder/MediaRecorderPrivateMock.cpp: 47 (WebCore::MediaRecorderPrivateMock::MediaRecorderPrivateMock): 48 (WebCore::MediaRecorderPrivateMock::~MediaRecorderPrivateMock): 49 (WebCore::MediaRecorderPrivateMock::stopRecording): 50 (WebCore::MediaRecorderPrivateMock::videoSampleAvailable): 51 (WebCore::MediaRecorderPrivateMock::sampleBufferUpdated): Deleted. 52 * platform/mediarecorder/MediaRecorderPrivateMock.h: 53 * platform/mediastream/MediaStreamTrackPrivate.cpp: 54 (WebCore::MediaStreamTrackPrivate::hasStartedProducingData): 55 (WebCore::MediaStreamTrackPrivate::updateReadyState): 56 (WebCore::MediaStreamTrackPrivate::videoSampleAvailable): Deleted. 57 (WebCore::MediaStreamTrackPrivate::hasStartedProducingAudioData): Deleted. 58 * platform/mediastream/MediaStreamTrackPrivate.h: 59 * platform/mediastream/RealtimeMediaSource.cpp: 60 (WebCore::RealtimeMediaSource::addVideoSampleObserver): 61 (WebCore::RealtimeMediaSource::removeVideoSampleObserver): 62 (WebCore::RealtimeMediaSource::updateHasStartedProducingData): 63 (WebCore::RealtimeMediaSource::videoSampleAvailable): 64 (WebCore::RealtimeMediaSource::audioSamplesAvailable): 65 * platform/mediastream/RealtimeMediaSource.h: 66 * platform/mediastream/RealtimeOutgoingVideoSource.cpp: 67 (WebCore::RealtimeOutgoingVideoSource::unobserveSource): 68 (WebCore::RealtimeOutgoingVideoSource::updateBlackFramesSending): 69 * platform/mediastream/RealtimeOutgoingVideoSource.h: 70 * platform/mediastream/RealtimeVideoSource.cpp: 71 (WebCore::RealtimeVideoSource::~RealtimeVideoSource): 72 (WebCore::RealtimeVideoSource::startProducingData): 73 (WebCore::RealtimeVideoSource::stopProducingData): 74 (WebCore::RealtimeVideoSource::videoSampleAvailable): 75 * platform/mediastream/RealtimeVideoSource.h: 76 * platform/mediastream/mac/AVVideoCaptureSource.mm: 77 (WebCore::AVVideoCaptureSource::captureOutputDidOutputSampleBufferFromConnection): 78 * platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.h: 79 * platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.mm: 80 (WebCore::RealtimeIncomingVideoSourceCocoa::processNewSample): 81 * platform/mediastream/mac/RealtimeOutgoingVideoSourceCocoa.cpp: 82 (WebCore::RealtimeOutgoingVideoSourceCocoa::videoSampleAvailable): 83 (WebCore::RealtimeOutgoingVideoSourceCocoa::sampleBufferUpdated): Deleted. 84 * platform/mediastream/mac/RealtimeOutgoingVideoSourceCocoa.h: 85 * platform/mock/MockRealtimeVideoSource.cpp: 86 * testing/Internals.cpp: 87 (WebCore::Internals::~Internals): 88 (WebCore::Internals::stopObservingRealtimeMediaSource): 89 (WebCore::Internals::observeMediaStreamTrack): 90 * testing/Internals.h: 91 1 92 2020-05-12 Philippe Normand <pnormand@igalia.com> 2 93 -
trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp
r260379 r261553 223 223 } 224 224 225 void MediaRecorder::sampleBufferUpdated(MediaStreamTrackPrivate& track, MediaSample& mediaSample)226 {227 m_private->sampleBufferUpdated(track, mediaSample);228 }229 230 225 bool MediaRecorder::virtualHasPendingActivity() const 231 226 { -
trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.h
r260379 r261553 109 109 void trackSettingsChanged(MediaStreamTrackPrivate&) final { }; 110 110 void trackEnabledChanged(MediaStreamTrackPrivate&) final { }; 111 void sampleBufferUpdated(MediaStreamTrackPrivate&, MediaSample&) final;112 111 113 112 static CreatorFunction m_customCreator; -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h
r260241 r261553 52 52 class VideoTrackPrivateMediaStream; 53 53 54 class MediaPlayerPrivateMediaStreamAVFObjC final : public MediaPlayerPrivateInterface, private MediaStreamPrivate::Observer, public MediaStreamTrackPrivate::Observer, public SampleBufferDisplayLayer::Client 54 class MediaPlayerPrivateMediaStreamAVFObjC final 55 : public MediaPlayerPrivateInterface 56 , private MediaStreamPrivate::Observer 57 , public MediaStreamTrackPrivate::Observer 58 , public RealtimeMediaSource::VideoSampleObserver 59 , public SampleBufferDisplayLayer::Client 55 60 , private LoggerHelper 56 61 { … … 135 140 MediaTime calculateTimelineOffset(const MediaSample&, double); 136 141 137 void enqueueVideoSample(MediaS treamTrackPrivate&, MediaSample&);142 void enqueueVideoSample(MediaSample&); 138 143 void enqueueCorrectedVideoSample(MediaSample&); 139 144 void requestNotificationWhenReadyForVideoData(); … … 198 203 void trackSettingsChanged(MediaStreamTrackPrivate&) override { }; 199 204 void trackEnabledChanged(MediaStreamTrackPrivate&) override { }; 200 void sampleBufferUpdated(MediaStreamTrackPrivate&, MediaSample&) override;201 205 void readyStateChanged(MediaStreamTrackPrivate&) override; 206 207 // RealtimeMediaSouce::VideoSampleObserver 208 void videoSampleAvailable(MediaSample&) final; 202 209 203 210 RetainPtr<PlatformLayer> createVideoFullscreenLayer() override; -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm
r261172 r261553 156 156 track->pause(); 157 157 158 if (m_mediaStreamPrivate) {158 if (m_mediaStreamPrivate) 159 159 m_mediaStreamPrivate->removeObserver(*this); 160 160 161 for (auto& track : m_audioTrackMap.values()) 162 track->streamTrack().removeObserver(*this); 163 164 for (auto& track : m_videoTrackMap.values()) 165 track->streamTrack().removeObserver(*this); 166 } 161 for (auto& track : m_audioTrackMap.values()) 162 track->streamTrack().removeObserver(*this); 163 164 for (auto& track : m_videoTrackMap.values()) 165 track->streamTrack().removeObserver(*this); 166 167 if (m_activeVideoTrack) 168 m_activeVideoTrack->source().removeVideoSampleObserver(*this); 167 169 168 170 [m_boundsChangeListener invalidate]; … … 280 282 } 281 283 282 void MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSample(MediaStreamTrackPrivate& track, MediaSample& sample) 283 { 284 if (&track != activeVideoTrack()) 285 return; 286 284 void MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSample(MediaSample& sample) 285 { 287 286 if (!m_imagePainter.mediaSample || m_displayMode != PausedImage) { 288 287 m_imagePainter.mediaSample = &sample; … … 295 294 return; 296 295 297 auto videoTrack = m_videoTrackMap.get(track.id()); 296 // FIXME: We should not query the map each time we get a sample. 297 auto videoTrack = m_videoTrackMap.get(m_activeVideoTrack->id()); 298 298 MediaTime timelineOffset = videoTrack->timelineOffset(); 299 299 if (timelineOffset == MediaTime::invalidTime()) { … … 301 301 videoTrack->setTimelineOffset(timelineOffset); 302 302 303 INFO_LOG(LOGIDENTIFIER, "timeline offset for track ", track.id(), " set to ", timelineOffset);303 INFO_LOG(LOGIDENTIFIER, "timeline offset for track ", m_activeVideoTrack->id(), " set to ", timelineOffset); 304 304 } 305 305 … … 472 472 MediaPlayerPrivateMediaStreamAVFObjC::DisplayMode MediaPlayerPrivateMediaStreamAVFObjC::currentDisplayMode() const 473 473 { 474 if (m_intrinsicSize.isEmpty() || !metaDataAvailable() || !m_sampleBufferDisplayLayer)474 if (m_intrinsicSize.isEmpty() || !metaDataAvailable()) 475 475 return None; 476 476 … … 736 736 } 737 737 738 void MediaPlayerPrivateMediaStreamAVFObjC::sampleBufferUpdated(MediaStreamTrackPrivate& track, MediaSample& mediaSample) 739 { 740 ASSERT(track.id() == mediaSample.trackID()); 741 ASSERT(mediaSample.platformSample().type == PlatformSample::CMSampleBufferType); 742 ASSERT(m_mediaStreamPrivate); 743 738 void MediaPlayerPrivateMediaStreamAVFObjC::videoSampleAvailable(MediaSample& mediaSample) 739 { 744 740 if (streamTime().toDouble() < 0) 745 741 return; 746 742 747 switch (track.type()) { 748 case RealtimeMediaSource::Type::None: 749 // Do nothing. 750 break; 751 case RealtimeMediaSource::Type::Audio: 752 break; 753 case RealtimeMediaSource::Type::Video: 754 if (&track == m_activeVideoTrack.get()) 755 enqueueVideoSample(track, mediaSample); 756 break; 757 } 743 enqueueVideoSample(mediaSample); 758 744 } 759 745 … … 852 838 auto oldVideoTrack = m_activeVideoTrack; 853 839 bool hideVideoLayer = true; 840 854 841 m_activeVideoTrack = nullptr; 855 842 if (auto* activeVideoTrack = this->activeVideoTrack()) { … … 878 865 m_pendingSelectedTrackCheck = false; 879 866 updateDisplayMode(); 867 868 if (oldVideoTrack != m_activeVideoTrack) { 869 if (oldVideoTrack) 870 oldVideoTrack->source().removeVideoSampleObserver(*this); 871 if (m_activeVideoTrack) 872 m_activeVideoTrack->source().addVideoSampleObserver(*this); 873 } 880 874 }); 881 875 } -
trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h
r259861 r261553 45 45 class SharedBuffer; 46 46 47 class MediaRecorderPrivate : 48 public RealtimeMediaSource::AudioSampleObserver { 47 class MediaRecorderPrivate 48 : public RealtimeMediaSource::AudioSampleObserver 49 , public RealtimeMediaSource::VideoSampleObserver { 49 50 public: 50 51 ~MediaRecorderPrivate(); … … 55 56 }; 56 57 WEBCORE_EXPORT static AudioVideoSelectedTracks selectTracks(MediaStreamPrivate&); 57 58 virtual void sampleBufferUpdated(const MediaStreamTrackPrivate&, MediaSample&) = 0;59 58 60 59 using FetchDataCallback = CompletionHandler<void(RefPtr<SharedBuffer>&&, const String& mimeType)>; … … 67 66 protected: 68 67 void setAudioSource(RefPtr<RealtimeMediaSource>&&); 68 void setVideoSource(RefPtr<RealtimeMediaSource>&&); 69 69 70 70 protected: … … 73 73 private: 74 74 RefPtr<RealtimeMediaSource> m_audioSource; 75 RefPtr<RealtimeMediaSource> m_videoSource; 75 76 }; 76 77 … … 86 87 } 87 88 89 inline void MediaRecorderPrivate::setVideoSource(RefPtr<RealtimeMediaSource>&& videoSource) 90 { 91 if (m_videoSource) 92 m_videoSource->removeVideoSampleObserver(*this); 93 94 m_videoSource = WTFMove(videoSource); 95 96 if (m_videoSource) 97 m_videoSource->addVideoSampleObserver(*this); 98 } 99 88 100 inline MediaRecorderPrivate::~MediaRecorderPrivate() 89 101 { 102 // Subclasses should stop observing sonner than here. Otherwise they might be called from a background thread while half destroyed 103 ASSERT(!m_audioSource); 104 ASSERT(!m_videoSource); 90 105 if (m_audioSource) 91 106 m_audioSource->removeAudioSampleObserver(*this); 107 if (m_videoSource) 108 m_videoSource->removeVideoSampleObserver(*this); 92 109 } 93 110 -
trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp
r259861 r261553 60 60 if (selectedTracks.audioTrack) 61 61 recorder->setAudioSource(&selectedTracks.audioTrack->source()); 62 if (selectedTracks.videoTrack) 63 recorder->setVideoSource(&selectedTracks.videoTrack->source()); 62 64 return recorder; 63 65 } … … 73 75 { 74 76 setAudioSource(nullptr); 77 setVideoSource(nullptr); 75 78 } 76 79 77 void MediaRecorderPrivateAVFImpl:: sampleBufferUpdated(const MediaStreamTrackPrivate& track,MediaSample& sampleBuffer)80 void MediaRecorderPrivateAVFImpl::videoSampleAvailable(MediaSample& sampleBuffer) 78 81 { 79 if (track.id() != m_recordedVideoTrackID)80 return;81 82 m_writer->appendVideoSampleBuffer(sampleBuffer.platformSample().sample.cmSampleBuffer); 82 83 } … … 92 93 { 93 94 setAudioSource(nullptr); 95 setVideoSource(nullptr); 94 96 m_writer->stopRecording(); 95 97 } -
trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.h
r259861 r261553 47 47 48 48 // MediaRecorderPrivate 49 void sampleBufferUpdated(const MediaStreamTrackPrivate&,MediaSample&) final;49 void videoSampleAvailable(MediaSample&) final; 50 50 void fetchData(FetchDataCallback&&) final; 51 51 void audioSamplesAvailable(const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final; -
trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateMock.cpp
r259861 r261553 41 41 setAudioSource(&selectedTracks.audioTrack->source()); 42 42 } 43 if (selectedTracks.videoTrack) 43 if (selectedTracks.videoTrack) { 44 44 m_videoTrackID = selectedTracks.videoTrack->id(); 45 setVideoSource(&selectedTracks.videoTrack->source()); 46 } 45 47 } 46 48 … … 48 50 { 49 51 setAudioSource(nullptr); 52 setVideoSource(nullptr); 50 53 } 51 54 … … 53 56 { 54 57 setAudioSource(nullptr); 58 setVideoSource(nullptr); 55 59 } 56 60 57 void MediaRecorderPrivateMock:: sampleBufferUpdated(const MediaStreamTrackPrivate&,MediaSample&)61 void MediaRecorderPrivateMock::videoSampleAvailable(MediaSample&) 58 62 { 59 63 auto locker = holdLock(m_bufferLock); -
trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateMock.h
r259861 r261553 43 43 private: 44 44 // MediaRecorderPrivate 45 void sampleBufferUpdated(const MediaStreamTrackPrivate&,MediaSample&) final;45 void videoSampleAvailable(MediaSample&) final; 46 46 void fetchData(FetchDataCallback&&) final; 47 47 void audioSamplesAvailable(const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final; -
trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp
r261172 r261553 237 237 } 238 238 239 void MediaStreamTrackPrivate::videoSampleAvailable(MediaSample& mediaSample) 240 { 241 ASSERT(isMainThread()); 242 if (!m_haveProducedData) { 243 m_haveProducedData = true; 244 updateReadyState(); 245 } 246 247 if (!enabled()) 248 return; 249 250 mediaSample.setTrackID(id()); 251 forEachObserver([&](auto& observer) { 252 observer.sampleBufferUpdated(*this, mediaSample); 253 }); 254 } 255 256 void MediaStreamTrackPrivate::hasStartedProducingAudioData() 257 { 258 if (m_haveProducedData) 259 return; 260 m_haveProducedData = true; 239 void MediaStreamTrackPrivate::hasStartedProducingData() 240 { 241 ASSERT(isMainThread()); 242 if (m_hasStartedProducingData) 243 return; 244 m_hasStartedProducingData = true; 261 245 updateReadyState(); 262 246 } … … 268 252 if (m_isEnded) 269 253 state = ReadyState::Ended; 270 else if (m_ha veProducedData)254 else if (m_hasStartedProducingData) 271 255 state = ReadyState::Live; 272 256 -
trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h
r260241 r261553 60 60 virtual void trackSettingsChanged(MediaStreamTrackPrivate&) = 0; 61 61 virtual void trackEnabledChanged(MediaStreamTrackPrivate&) = 0; 62 virtual void sampleBufferUpdated(MediaStreamTrackPrivate&, MediaSample&) { };63 62 virtual void readyStateChanged(MediaStreamTrackPrivate&) { }; 64 63 }; … … 134 133 void sourceSettingsChanged() final; 135 134 bool preventSourceFromStopping() final; 136 void videoSampleAvailable(MediaSample&) final;137 135 void audioUnitWillStart() final; 138 void hasStartedProducing AudioData() final;136 void hasStartedProducingData() final; 139 137 140 138 void updateReadyState(); … … 154 152 bool m_isEnabled { true }; 155 153 bool m_isEnded { false }; 156 bool m_haveProducedData { false }; 157 bool m_hasSentStartProducedData { false }; 154 bool m_hasStartedProducingData { false }; 158 155 HintValue m_contentHint { HintValue::Empty }; 159 156 RefPtr<WebAudioSourceProvider> m_audioSourceProvider; -
trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp
r261373 r261553 75 75 } 76 76 77 void RealtimeMediaSource::addVideoSampleObserver(VideoSampleObserver& observer) 78 { 79 ASSERT(isMainThread()); 80 auto locker = holdLock(m_videoSampleObserversLock); 81 m_videoSampleObservers.add(&observer); 82 } 83 84 void RealtimeMediaSource::removeVideoSampleObserver(VideoSampleObserver& observer) 85 { 86 ASSERT(isMainThread()); 87 auto locker = holdLock(m_videoSampleObserversLock); 88 m_videoSampleObservers.remove(&observer); 89 } 90 77 91 void RealtimeMediaSource::addObserver(Observer& observer) 78 92 { … … 155 169 } 156 170 171 void RealtimeMediaSource::updateHasStartedProducingData() 172 { 173 if (m_hasStartedProducingData) 174 return; 175 176 callOnMainThread([this, weakThis = makeWeakPtr(this)] { 177 if (!weakThis) 178 return; 179 if (m_hasStartedProducingData) 180 return; 181 m_hasStartedProducingData = true; 182 forEachObserver([&](auto& observer) { 183 observer.hasStartedProducingData(); 184 }); 185 }); 186 } 187 157 188 void RealtimeMediaSource::videoSampleAvailable(MediaSample& mediaSample) 158 189 { 190 // FIXME: Migrate RealtimeMediaSource clients to non main thread processing. 191 ASSERT(isMainThread()); 159 192 #if !RELEASE_LOG_DISABLED 160 193 ++m_frameCount; … … 171 204 #endif 172 205 173 forEachObserver([&](auto& observer) { 174 observer.videoSampleAvailable(mediaSample); 175 }); 206 updateHasStartedProducingData(); 207 208 auto locker = holdLock(m_videoSampleObserversLock); 209 for (auto* observer : m_videoSampleObservers) 210 observer->videoSampleAvailable(mediaSample); 176 211 } 177 212 178 213 void RealtimeMediaSource::audioSamplesAvailable(const MediaTime& time, const PlatformAudioData& audioData, const AudioStreamDescription& description, size_t numberOfFrames) 179 214 { 180 if (!m_hasSentStartProducedAudioData) { 181 callOnMainThread([this, weakThis = makeWeakPtr(this)] { 182 if (!weakThis) 183 return; 184 if (m_hasSentStartProducedAudioData) 185 return; 186 m_hasSentStartProducedAudioData = true; 187 forEachObserver([&](auto& observer) { 188 observer.hasStartedProducingAudioData(); 189 }); 190 }); 191 } 215 updateHasStartedProducingData(); 192 216 193 217 auto locker = holdLock(m_audioSampleObserversLock); -
trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h
r261373 r261553 90 90 virtual bool preventSourceFromStopping() { return false; } 91 91 92 // Called on the main thread. 93 virtual void videoSampleAvailable(MediaSample&) { } 94 95 virtual void hasStartedProducingAudioData() { } 92 virtual void hasStartedProducingData() { } 96 93 }; 97 94 class AudioSampleObserver { … … 102 99 virtual void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t /*numberOfFrames*/) = 0; 103 100 }; 101 class VideoSampleObserver { 102 public: 103 virtual ~VideoSampleObserver() = default; 104 105 virtual void videoSampleAvailable(MediaSample&) { } 106 }; 104 107 105 108 virtual ~RealtimeMediaSource() = default; … … 139 142 WEBCORE_EXPORT void addAudioSampleObserver(AudioSampleObserver&); 140 143 WEBCORE_EXPORT void removeAudioSampleObserver(AudioSampleObserver&); 144 145 WEBCORE_EXPORT void addVideoSampleObserver(VideoSampleObserver&); 146 WEBCORE_EXPORT void removeVideoSampleObserver(VideoSampleObserver&); 141 147 142 148 const IntSize size() const; … … 251 257 virtual void hasEnded() { } 252 258 259 void updateHasStartedProducingData(); 260 253 261 #if !RELEASE_LOG_DISABLED 254 262 RefPtr<const Logger> m_logger; … … 267 275 mutable RecursiveLock m_audioSampleObserversLock; 268 276 HashSet<AudioSampleObserver*> m_audioSampleObservers; 277 278 mutable RecursiveLock m_videoSampleObserversLock; 279 HashSet<VideoSampleObserver*> m_videoSampleObservers; 269 280 270 281 IntSize m_size; … … 285 296 bool m_captureDidFailed { false }; 286 297 bool m_isEnded { false }; 287 bool m_hasS entStartProducedAudioData { false };298 bool m_hasStartedProducingData { false }; 288 299 }; 289 300 -
trunk/Source/WebCore/platform/mediastream/RealtimeOutgoingVideoSource.cpp
r259289 r261553 75 75 { 76 76 m_videoSource->removeObserver(*this); 77 m_videoSource->source().removeVideoSampleObserver(*this); 77 78 } 78 79 … … 115 116 { 116 117 if (!m_muted && m_enabled) { 118 m_videoSource->source().addVideoSampleObserver(*this); 117 119 if (m_blackFrameTimer.isActive()) 118 120 m_blackFrameTimer.stop(); … … 120 122 } 121 123 124 m_videoSource->source().removeVideoSampleObserver(*this); 122 125 sendBlackFramesIfNeeded(); 123 126 } -
trunk/Source/WebCore/platform/mediastream/RealtimeOutgoingVideoSource.h
r260241 r261553 52 52 , public webrtc::VideoTrackSourceInterface 53 53 , private MediaStreamTrackPrivate::Observer 54 , private RealtimeMediaSource::VideoSampleObserver 54 55 #if !RELEASE_LOG_DISABLED 55 56 , private LoggerHelper … … 129 130 void trackEnabledChanged(MediaStreamTrackPrivate&) final { sourceEnabledChanged(); } 130 131 void trackSettingsChanged(MediaStreamTrackPrivate&) final { initializeFromSource(); } 131 void sampleBufferUpdated(MediaStreamTrackPrivate&, MediaSample&) override { }132 132 void trackEnded(MediaStreamTrackPrivate&) final { } 133 134 // RealtimeMediaSource::VideoSampleObserver API 135 void videoSampleAvailable(MediaSample&) override { } 133 136 134 137 Ref<MediaStreamTrackPrivate> m_videoSource; -
trunk/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp
r260364 r261553 47 47 RealtimeVideoSource::~RealtimeVideoSource() 48 48 { 49 m_source->removeVideoSampleObserver(*this); 49 50 m_source->removeObserver(*this); 50 51 } … … 53 54 { 54 55 m_source->start(); 56 m_source->addVideoSampleObserver(*this); 55 57 } 56 58 57 59 void RealtimeVideoSource::stopProducingData() 58 60 { 61 m_source->removeVideoSampleObserver(*this); 59 62 m_source->stop(); 60 63 } … … 167 170 void RealtimeVideoSource::videoSampleAvailable(MediaSample& sample) 168 171 { 169 if (!isProducingData())170 return;171 172 172 if (m_frameDecimation > 1 && ++m_frameDecimationCounter % m_frameDecimation) 173 173 return; -
trunk/Source/WebCore/platform/mediastream/RealtimeVideoSource.h
r261373 r261553 34 34 class ImageTransferSessionVT; 35 35 36 class RealtimeVideoSource final : public RealtimeMediaSource, public RealtimeMediaSource::Observer { 36 class RealtimeVideoSource final 37 : public RealtimeMediaSource 38 , public RealtimeMediaSource::Observer 39 , public RealtimeMediaSource::VideoSampleObserver { 37 40 public: 38 41 static Ref<RealtimeVideoSource> create(Ref<RealtimeVideoCaptureSource>&& source) { return adoptRef(*new RealtimeVideoSource(WTFMove(source))); } … … 59 62 bool isSameAs(RealtimeMediaSource& source) const final { return this == &source || m_source.ptr() == &source; } 60 63 61 // Observer64 // RealtimeMediaSource::Observer 62 65 void sourceMutedChanged() final; 63 66 void sourceSettingsChanged() final; 64 67 void sourceStopped() final; 65 68 bool preventSourceFromStopping() final; 69 70 // RealtimeMediaSource::VideoSampleObserver 66 71 void videoSampleAvailable(MediaSample&) final; 67 72 -
trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp
r260937 r261553 108 108 class WebKitMediaStreamTrackObserver 109 109 : public MediaStreamTrackPrivate::Observer 110 , public RealtimeMediaSource::AudioSampleObserver { 110 , public RealtimeMediaSource::AudioSampleObserver 111 , public RealtimeMediaSource::VideoSampleObserver { 111 112 WTF_MAKE_FAST_ALLOCATED; 112 113 public: … … 131 132 void readyStateChanged(MediaStreamTrackPrivate&) final { }; 132 133 133 void sampleBufferUpdated(MediaStreamTrackPrivate&,MediaSample& sample) final134 void videoSampleAvailable(MediaSample& sample) final 134 135 { 135 136 if (!m_enabled) … … 388 389 for (auto& track : self->stream->tracks()) { 389 390 track->source().removeAudioSampleObserver(*self->mediaStreamTrackObserver.get()); 391 track->source().removeVideoSampleObserver(*self->mediaStreamTrackObserver.get()); 390 392 track->removeObserver(*self->mediaStreamTrackObserver.get()); 391 393 } … … 410 412 for (auto& track : self->stream->tracks()) { 411 413 track->source().removeAudioSampleObserver(*self->mediaStreamTrackObserver.get()); 414 track->source().removeVideoSampleObserver(*self->mediaStreamTrackObserver.get()); 412 415 track->removeObserver(*self->mediaStreamTrackObserver.get()); 413 416 } 414 417 } else if (self->track) { 415 418 self->track->source().removeAudioSampleObserver(*self->mediaStreamTrackObserver.get()); 419 self->track->source().removeVideoSampleObserver(*self->mediaStreamTrackObserver.get()); 416 420 self->track->removeObserver(*self->mediaStreamTrackObserver.get()); 417 421 } … … 561 565 if (observe_track) { 562 566 track->addObserver(*self->mediaStreamTrackObserver.get()); 563 track->source().addAudioSampleObserver(*self->mediaStreamTrackObserver.get()); 567 auto& source = track->source(); 568 switch (source.type()) { 569 case RealtimeMediaSource::Type::Audio: 570 source.addAudioSampleObserver(*self->mediaStreamTrackObserver.get()); 571 break; 572 case RealtimeMediaSource::Type::Video: 573 source.addVideoSampleObserver(*self->mediaStreamTrackObserver.get()); 574 break; 575 case RealtimeMediaSource::Type::None: 576 ASSERT_NOT_REACHED(); 577 } 564 578 } 565 579 gst_element_sync_state_with_parent(element); -
trunk/Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingVideoSourceLibWebRTC.cpp
r239921 r261553 51 51 } 52 52 53 void RealtimeOutgoingVideoSourceLibWebRTC:: sampleBufferUpdated(MediaStreamTrackPrivate&,MediaSample& sample)53 void RealtimeOutgoingVideoSourceLibWebRTC::videoSampleAvailable(MediaSample& sample) 54 54 { 55 if (isSilenced())56 return;57 58 55 switch (sample.videoRotation()) { 59 56 case MediaSample::VideoRotation::None: -
trunk/Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingVideoSourceLibWebRTC.h
r237861 r261553 42 42 rtc::scoped_refptr<webrtc::VideoFrameBuffer> createBlackFrame(size_t, size_t) final; 43 43 44 // MediaStreamTrackPrivate::Observer API45 void sampleBufferUpdated(MediaStreamTrackPrivate&,MediaSample&) final;44 // RealtimeMediaSource::VideoSampleObserver API 45 void videoSampleAvailable(MediaSample&) final; 46 46 }; 47 47 -
trunk/Source/WebCore/platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.h
r236445 r261553 51 51 void OnFrame(const webrtc::VideoFrame&) final; 52 52 53 RetainPtr<CMSampleBufferRef> m_buffer;54 53 RetainPtr<CVPixelBufferRef> m_blackFrame; 55 54 int m_blackFrameWidth { 0 }; -
trunk/Source/WebCore/platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.mm
r260366 r261553 201 201 void RealtimeIncomingVideoSourceCocoa::processNewSample(CMSampleBufferRef sample, unsigned width, unsigned height, MediaSample::VideoRotation rotation) 202 202 { 203 m_buffer = sample;204 203 auto size = this->size(); 205 204 if (WTF::safeCast<int>(width) != size.width() || WTF::safeCast<int>(height) != size.height()) -
trunk/Source/WebCore/platform/mediastream/mac/RealtimeOutgoingVideoSourceCocoa.cpp
r246759 r261553 63 63 } 64 64 65 void RealtimeOutgoingVideoSourceCocoa:: sampleBufferUpdated(MediaStreamTrackPrivate&,MediaSample& sample)65 void RealtimeOutgoingVideoSourceCocoa::videoSampleAvailable(MediaSample& sample) 66 66 { 67 if (isSilenced())68 return;69 70 67 #if !RELEASE_LOG_DISABLED 71 68 if (!(++m_numberOfFrames % 60)) -
trunk/Source/WebCore/platform/mediastream/mac/RealtimeOutgoingVideoSourceCocoa.h
r246759 r261553 45 45 rtc::scoped_refptr<webrtc::VideoFrameBuffer> createBlackFrame(size_t width, size_t height) final; 46 46 47 // MediaStreamTrackPrivate::Observer API48 void sampleBufferUpdated(MediaStreamTrackPrivate&,MediaSample&) final;47 // RealtimeMediaSource::VideoSampleObserver API 48 void videoSampleAvailable(MediaSample&) final; 49 49 50 50 RetainPtr<CVPixelBufferRef> convertToYUV(CVPixelBufferRef); -
trunk/Source/WebCore/testing/Internals.cpp
r261500 r261553 477 477 { 478 478 #if ENABLE(MEDIA_STREAM) 479 if (m_trackSource) { 480 m_trackSource->removeObserver(*this); 481 m_trackSource->removeAudioSampleObserver(*this); 482 } 479 stopObservingRealtimeMediaSource(); 483 480 #endif 484 481 } … … 5040 5037 } 5041 5038 5039 void Internals::stopObservingRealtimeMediaSource() 5040 { 5041 if (!m_trackSource) 5042 return; 5043 5044 switch (m_trackSource->type()) { 5045 case RealtimeMediaSource::Type::Audio: 5046 m_trackSource->removeAudioSampleObserver(*this); 5047 break; 5048 case RealtimeMediaSource::Type::Video: 5049 m_trackSource->removeVideoSampleObserver(*this); 5050 break; 5051 case RealtimeMediaSource::Type::None: 5052 ASSERT_NOT_REACHED(); 5053 } 5054 m_trackSource->removeObserver(*this); 5055 5056 m_trackSource = nullptr; 5057 m_trackAudioSampleCount = 0; 5058 m_trackVideoSampleCount = 0; 5059 } 5060 5042 5061 void Internals::observeMediaStreamTrack(MediaStreamTrack& track) 5043 5062 { 5044 if (m_trackSource) { 5045 m_trackSource->removeObserver(*this); 5046 m_trackSource->removeAudioSampleObserver(*this); 5047 5048 m_trackAudioSampleCount = 0; 5049 m_trackVideoSampleCount = 0; 5050 } 5063 stopObservingRealtimeMediaSource(); 5051 5064 5052 5065 m_trackSource = &track.source(); 5053 5066 m_trackSource->addObserver(*this); 5054 m_trackSource->addAudioSampleObserver(*this); 5067 switch (m_trackSource->type()) { 5068 case RealtimeMediaSource::Type::Audio: 5069 m_trackSource->addAudioSampleObserver(*this); 5070 break; 5071 case RealtimeMediaSource::Type::Video: 5072 m_trackSource->addVideoSampleObserver(*this); 5073 break; 5074 case RealtimeMediaSource::Type::None: 5075 ASSERT_NOT_REACHED(); 5076 } 5055 5077 } 5056 5078 -
trunk/Source/WebCore/testing/Internals.h
r261479 r261553 131 131 , private RealtimeMediaSource::Observer 132 132 , private RealtimeMediaSource::AudioSampleObserver 133 , private RealtimeMediaSource::VideoSampleObserver 133 134 #endif 134 135 { … … 764 765 765 766 #if ENABLE(MEDIA_STREAM) 767 void stopObservingRealtimeMediaSource(); 768 766 769 void setMockAudioTrackChannelNumber(MediaStreamTrack&, unsigned short); 767 770 void setCameraMediaStreamTrackOrientation(MediaStreamTrack&, int orientation); -
trunk/Source/WebKit/ChangeLog
r261549 r261553 1 2020-05-12 Youenn Fablet <youenn@apple.com> 2 3 Introduce a RealtimeMediaSource video sample observer 4 https://bugs.webkit.org/show_bug.cgi?id=211718 5 6 Reviewed by Eric Carlson. 7 8 * UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp: 9 (WebKit::UserMediaCaptureManagerProxy::SourceProxy::SourceProxy): 10 (WebKit::UserMediaCaptureManagerProxy::SourceProxy::~SourceProxy): 11 * WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp: 12 (WebKit::MediaRecorderPrivate::MediaRecorderPrivate): 13 (WebKit::MediaRecorderPrivate::~MediaRecorderPrivate): 14 (WebKit::MediaRecorderPrivate::videoSampleAvailable): 15 (WebKit::MediaRecorderPrivate::stopRecording): 16 (WebKit::MediaRecorderPrivate::sampleBufferUpdated): Deleted. 17 * WebProcess/GPU/webrtc/MediaRecorderPrivate.h: 18 1 19 2020-05-12 Mark Lam <mark.lam@apple.com> 2 20 -
trunk/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp
r261375 r261553 51 51 52 52 class UserMediaCaptureManagerProxy::SourceProxy 53 : public RealtimeMediaSource::Observer 54 , public RealtimeMediaSource::AudioSampleObserver 53 : private RealtimeMediaSource::Observer 54 , private RealtimeMediaSource::AudioSampleObserver 55 , private RealtimeMediaSource::VideoSampleObserver 55 56 , public SharedRingBufferStorage::Client { 56 57 WTF_MAKE_FAST_ALLOCATED; … … 63 64 { 64 65 m_source->addObserver(*this); 65 m_source->addAudioSampleObserver(*this); 66 switch (m_source->type()) { 67 case RealtimeMediaSource::Type::Audio: 68 m_source->addAudioSampleObserver(*this); 69 break; 70 case RealtimeMediaSource::Type::Video: 71 m_source->addVideoSampleObserver(*this); 72 break; 73 case RealtimeMediaSource::Type::None: 74 ASSERT_NOT_REACHED(); 75 } 66 76 } 67 77 … … 69 79 { 70 80 storage().invalidate(); 71 m_source->removeAudioSampleObserver(*this); 81 82 switch (m_source->type()) { 83 case RealtimeMediaSource::Type::Audio: 84 m_source->removeAudioSampleObserver(*this); 85 break; 86 case RealtimeMediaSource::Type::Video: 87 m_source->removeVideoSampleObserver(*this); 88 break; 89 case RealtimeMediaSource::Type::None: 90 ASSERT_NOT_REACHED(); 91 } 72 92 m_source->removeObserver(*this); 73 93 } -
trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp
r261133 r261553 65 65 } 66 66 67 m_connection->sendWithAsyncReply(Messages::RemoteMediaRecorderManager::CreateRecorder { m_identifier, !!selectedTracks.audioTrack, width, height }, [this, weakThis = makeWeakPtr(this), audioTrack = makeRefPtr(selectedTracks.audioTrack) ](auto&& exception) {67 m_connection->sendWithAsyncReply(Messages::RemoteMediaRecorderManager::CreateRecorder { m_identifier, !!selectedTracks.audioTrack, width, height }, [this, weakThis = makeWeakPtr(this), audioTrack = makeRefPtr(selectedTracks.audioTrack), videoTrack = makeRefPtr(selectedTracks.videoTrack)](auto&& exception) { 68 68 if (!weakThis) 69 69 return; … … 72 72 if (audioTrack) 73 73 setAudioSource(&audioTrack->source()); 74 if (videoTrack) 75 setVideoSource(&videoTrack->source()); 74 76 }, 0); 75 77 } … … 78 80 { 79 81 setAudioSource(nullptr); 82 setVideoSource(nullptr); 80 83 m_connection->send(Messages::RemoteMediaRecorderManager::ReleaseRecorder { m_identifier }, 0); 81 84 } 82 85 83 void MediaRecorderPrivate:: sampleBufferUpdated(const WebCore::MediaStreamTrackPrivate& track, WebCore::MediaSample& sample)86 void MediaRecorderPrivate::videoSampleAvailable(MediaSample& sample) 84 87 { 85 if (track.id() != m_recordedVideoTrackID)86 return;87 88 if (auto remoteSample = RemoteVideoSample::create(sample)) 88 89 m_connection->send(Messages::RemoteMediaRecorder::VideoSampleAvailable { WTFMove(*remoteSample) }, m_identifier); … … 129 130 { 130 131 setAudioSource(nullptr); 132 setVideoSource(nullptr); 131 133 m_connection->send(Messages::RemoteMediaRecorder::StopRecording { }, m_identifier); 132 134 } -
trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.h
r259861 r261553 56 56 private: 57 57 // WebCore::MediaRecorderPrivate 58 void sampleBufferUpdated(const WebCore::MediaStreamTrackPrivate&,WebCore::MediaSample&) final;58 void videoSampleAvailable(WebCore::MediaSample&) final; 59 59 void fetchData(CompletionHandler<void(RefPtr<WebCore::SharedBuffer>&&, const String& mimeType)>&&) final; 60 60 void stopRecording() final;
Note: See TracChangeset
for help on using the changeset viewer.