Changeset 260245 in webkit
- Timestamp:
- Apr 17, 2020 7:22:23 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 8 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r260243 r260245 1 2020-04-17 Youenn Fablet <youenn@apple.com> 2 3 Safari doesn't apply frameRate limit when request stream from Camera 4 https://bugs.webkit.org/show_bug.cgi?id=210186 5 <rdar://problem/61452794> 6 7 Reviewed by Eric Carlson. 8 9 * fast/mediastream/mediastreamtrack-video-frameRate-clone-decreasing-expected.txt: Added. 10 * fast/mediastream/mediastreamtrack-video-frameRate-clone-decreasing.html: Added. 11 * fast/mediastream/mediastreamtrack-video-frameRate-clone-increasing-expected.txt: Added. 12 * fast/mediastream/mediastreamtrack-video-frameRate-clone-increasing.html: Added. 13 * fast/mediastream/mediastreamtrack-video-framerate-decreasing-expected.txt: added. 14 * fast/mediastream/mediastreamtrack-video-framerate-decreasing.html: added. 15 * fast/mediastream/mediastreamtrack-video-framerate-increasing-expected.txt: added. 16 * fast/mediastream/mediastreamtrack-video-framerate-increasing.html: added. 17 * webrtc/routines.js: 18 1 19 2020-04-17 Alexey Shvayka <shvaikalesh@gmail.com> 2 20 -
trunk/LayoutTests/webrtc/routines.js
r252681 r260245 226 226 return stats; 227 227 } 228 229 function getReceivedTrackStats(connection) 230 { 231 return connection.getStats().then((report) => { 232 var stats; 233 report.forEach((statItem) => { 234 if (statItem.type === "track") { 235 stats = statItem; 236 } 237 }); 238 return stats; 239 }); 240 } 241 242 async function computeFrameRate(stream, video) 243 { 244 if (window.internals) { 245 internals.observeMediaStreamTrack(stream.getVideoTracks()[0]); 246 await new Promise(resolve => setTimeout(resolve, 1000)); 247 return internals.trackVideoSampleCount; 248 } 249 250 let connection; 251 video.srcObject = await new Promise((resolve, reject) => { 252 createConnections((firstConnection) => { 253 firstConnection.addTrack(stream.getVideoTracks()[0], stream); 254 }, (secondConnection) => { 255 connection = secondConnection; 256 secondConnection.ontrack = (trackEvent) => { 257 resolve(trackEvent.streams[0]); 258 }; 259 }); 260 setTimeout(() => reject("Test timed out"), 5000); 261 }); 262 263 await video.play(); 264 265 const stats1 = await getReceivedTrackStats(connection); 266 await new Promise(resolve => setTimeout(resolve, 1000)); 267 const stats2 = await getReceivedTrackStats(connection); 268 return (stats2.framesReceived - stats1.framesReceived) * 1000 / (stats2.timestamp - stats1.timestamp); 269 } -
trunk/Source/WebCore/ChangeLog
r260243 r260245 1 2020-04-17 Youenn Fablet <youenn@apple.com> 2 3 Safari doesn't apply frameRate limit when request stream from Camera 4 https://bugs.webkit.org/show_bug.cgi?id=210186 5 <rdar://problem/61452794> 6 7 Reviewed by Eric Carlson. 8 9 Add support to RealtimeVideoSource to decimate the video samples based on the observed frame rate of its capture source. 10 This allows supporting two tracks using the same capture device, one track being low frame rate and the other one high frame rate. 11 12 Clean-up refactoring to make RealtimeVideoSource directly inherit from RealtimeVideoCaptureSource. 13 Migrate size and format of frame adaptation from RealtimeVideoCaptureSource to RealtimeVideoSource. 14 Fix mock capture source to update its frame rate when asked by applyConstraints. 15 16 Tests: fast/mediastream/mediastreamtrack-video-frameRate-clone-decreasing.html 17 fast/mediastream/mediastreamtrack-video-frameRate-clone-increasing.html 18 fast/mediastream/mediastreamtrack-video-frameRate-decreasing.html 19 fast/mediastream/mediastreamtrack-video-frameRate-increasing.html 20 21 * platform/mediastream/RealtimeVideoCaptureSource.cpp: 22 (WebCore::RealtimeVideoCaptureSource::dispatchMediaSampleToObservers): 23 (WebCore::RealtimeVideoCaptureSource::clientUpdatedSizeAndFrameRate): 24 * platform/mediastream/RealtimeVideoCaptureSource.h: 25 (WebCore::RealtimeVideoCaptureSource::observedFrameRate const): 26 * platform/mediastream/RealtimeVideoSource.cpp: 27 (WebCore::RealtimeVideoSource::RealtimeVideoSource): 28 (WebCore::m_source): 29 (WebCore::RealtimeVideoSource::adaptVideoSample): 30 (WebCore::RealtimeVideoSource::videoSampleAvailable): 31 * platform/mediastream/RealtimeVideoSource.h: 32 * platform/mock/MockRealtimeVideoSource.cpp: 33 (WebCore::MockRealtimeVideoSource::setFrameRateWithPreset): 34 * testing/Internals.cpp: 35 (WebCore::Internals::observeMediaStreamTrack): 36 1 37 2020-04-17 Alexey Shvayka <shvaikalesh@gmail.com> 2 38 -
trunk/Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.cpp
r258215 r260245 34 34 #include "RemoteVideoSample.h" 35 35 #include <wtf/JSONValues.h> 36 37 #if PLATFORM(COCOA)38 #include "ImageTransferSessionVT.h"39 #endif40 36 41 37 namespace WebCore { … … 377 373 } 378 374 379 RefPtr<MediaSample> RealtimeVideoCaptureSource::adaptVideoSample(MediaSample& sample)375 void RealtimeVideoCaptureSource::dispatchMediaSampleToObservers(MediaSample& sample) 380 376 { 381 377 MediaTime sampleTime = sample.presentationTime(); … … 391 387 m_observedFrameRate = (m_observedFrameTimeStamps.size() / interval); 392 388 393 auto mediaSample = makeRefPtr(&sample); 394 395 #if PLATFORM(COCOA) 396 auto size = this->size(); 397 if (!size.isEmpty() && size != expandedIntSize(sample.presentationSize())) { 398 399 if (!m_imageTransferSession || m_imageTransferSession->pixelFormat() != sample.videoPixelFormat()) 400 m_imageTransferSession = ImageTransferSessionVT::create(sample.videoPixelFormat()); 401 402 ASSERT(m_imageTransferSession); 403 if (m_imageTransferSession) { 404 mediaSample = m_imageTransferSession->convertMediaSample(sample, size); 405 if (!mediaSample) { 406 ASSERT_NOT_REACHED(); 407 return nullptr; 408 } 409 } 410 } 411 #endif 412 413 return mediaSample.releaseNonNull(); 414 } 415 416 void RealtimeVideoCaptureSource::dispatchMediaSampleToObservers(MediaSample& sample) 417 { 418 if (auto mediaSample = adaptVideoSample(sample)) 419 videoSampleAvailable(*mediaSample); 389 videoSampleAvailable(sample); 420 390 } 421 391 … … 428 398 if (height && *height < static_cast<int>(settings.height())) 429 399 height = { }; 430 431 // FIXME: handle frameRate potential increase. 432 if (!width && !height) 400 if (frameRate && *frameRate < static_cast<double>(settings.frameRate())) 401 frameRate = { }; 402 403 if (!width && !height && !frameRate) 433 404 return; 434 405 -
trunk/Source/WebCore/platform/mediastream/RealtimeVideoCaptureSource.h
r246644 r260245 49 49 virtual MediaSample::VideoRotation sampleRotation() const { return MediaSample::VideoRotation::None; } 50 50 51 double observedFrameRate() const { return m_observedFrameRate; } 52 51 53 protected: 52 54 RealtimeVideoCaptureSource(String&& name, String&& id, String&& hashSalt); … … 70 72 void setDefaultSize(const IntSize& size) { m_defaultSize = size; } 71 73 72 double observedFrameRate() const { return m_observedFrameRate; }73 74 74 void dispatchMediaSampleToObservers(MediaSample&); 75 75 const Vector<IntSize>& standardVideoSizes(); 76 RefPtr<MediaSample> adaptVideoSample(MediaSample&);77 76 78 77 private: … … 94 93 double m_observedFrameRate { 0 }; 95 94 IntSize m_defaultSize; 96 #if PLATFORM(COCOA)97 std::unique_ptr<ImageTransferSessionVT> m_imageTransferSession;98 #endif99 95 }; 100 96 -
trunk/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp
r257919 r260245 29 29 #if ENABLE(MEDIA_STREAM) 30 30 31 #if PLATFORM(COCOA) 32 #include "ImageTransferSessionVT.h" 33 #endif 34 31 35 namespace WebCore { 32 36 33 37 RealtimeVideoSource::RealtimeVideoSource(Ref<RealtimeVideoCaptureSource>&& source) 34 : Realtime VideoCaptureSource(String { source->name() }, String { source->persistentID() }, String { source->deviceIDHashSalt() })38 : RealtimeMediaSource(Type::Video, String { source->name() }, String { source->persistentID() }, String { source->deviceIDHashSalt() }) 35 39 , m_source(WTFMove(source)) 36 40 { … … 38 42 m_currentSettings = m_source->settings(); 39 43 setSize(m_source->size()); 44 setFrameRate(m_source->frameRate()); 40 45 } 41 46 … … 143 148 } 144 149 150 #if PLATFORM(COCOA) 151 RefPtr<MediaSample> RealtimeVideoSource::adaptVideoSample(MediaSample& sample) 152 { 153 if (!m_imageTransferSession || m_imageTransferSession->pixelFormat() != sample.videoPixelFormat()) 154 m_imageTransferSession = ImageTransferSessionVT::create(sample.videoPixelFormat()); 155 156 ASSERT(m_imageTransferSession); 157 if (!m_imageTransferSession) 158 return nullptr; 159 160 auto mediaSample = m_imageTransferSession->convertMediaSample(sample, size()); 161 ASSERT(mediaSample); 162 163 return mediaSample; 164 } 165 #endif 166 145 167 void RealtimeVideoSource::videoSampleAvailable(MediaSample& sample) 146 168 { … … 148 170 return; 149 171 150 if (auto mediaSample = adaptVideoSample(sample)) 151 RealtimeMediaSource::videoSampleAvailable(*mediaSample); 172 if (m_frameDecimation > 1 && ++m_frameDecimationCounter % m_frameDecimation) 173 return; 174 175 m_frameDecimation = static_cast<size_t>(m_source->observedFrameRate() / frameRate()); 176 if (!m_frameDecimation) 177 m_frameDecimation = 1; 178 179 #if PLATFORM(COCOA) 180 auto size = this->size(); 181 if (!size.isEmpty() && size != expandedIntSize(sample.presentationSize())) { 182 if (auto mediaSample = adaptVideoSample(sample)) { 183 RealtimeMediaSource::videoSampleAvailable(*mediaSample); 184 return; 185 } 186 } 187 #endif 188 189 RealtimeMediaSource::videoSampleAvailable(sample); 152 190 } 153 191 -
trunk/Source/WebCore/platform/mediastream/RealtimeVideoSource.h
r258698 r260245 32 32 namespace WebCore { 33 33 34 // FIXME: Make RealtimeVideoSource derive from RealtimeMediaSource directly. 35 class RealtimeVideoSource final : public RealtimeVideoCaptureSource, public RealtimeMediaSource::Observer { 34 class ImageTransferSessionVT; 35 36 class RealtimeVideoSource final : public RealtimeMediaSource, public RealtimeMediaSource::Observer { 36 37 public: 37 38 static Ref<RealtimeVideoSource> create(Ref<RealtimeVideoCaptureSource>&& source) { return adoptRef(*new RealtimeVideoSource(WTFMove(source))); } … … 52 53 const RealtimeMediaSourceCapabilities& capabilities() final { return m_source->capabilities(); } 53 54 const RealtimeMediaSourceSettings& settings() final { return m_currentSettings; } 54 void generatePresets() final { m_source->generatePresets(); }55 55 bool isCaptureSource() const final { return m_source->isCaptureSource(); } 56 56 CaptureDevice::DeviceType deviceType() const final { return m_source->deviceType(); } … … 65 65 void videoSampleAvailable(MediaSample&) final; 66 66 67 #if PLATFORM(COCOA) 68 RefPtr<MediaSample> adaptVideoSample(MediaSample&); 69 #endif 70 67 71 #if !RELEASE_LOG_DISABLED 68 72 void setLogger(const Logger&, const void*) final; … … 71 75 Ref<RealtimeVideoCaptureSource> m_source; 72 76 RealtimeMediaSourceSettings m_currentSettings; 77 #if PLATFORM(COCOA) 78 std::unique_ptr<ImageTransferSessionVT> m_imageTransferSession; 79 #endif 80 size_t m_frameDecimation { 1 }; 81 size_t m_frameDecimationCounter { 0 }; 73 82 #if !RELEASE_LOG_DISABLED 74 83 uint64_t m_cloneCounter { 0 }; -
trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp
r259845 r260245 188 188 } 189 189 190 void MockRealtimeVideoSource::setFrameRateWithPreset(double , RefPtr<VideoPreset> preset)190 void MockRealtimeVideoSource::setFrameRateWithPreset(double frameRate, RefPtr<VideoPreset> preset) 191 191 { 192 192 m_preset = WTFMove(preset); 193 193 if (m_preset) 194 194 setIntrinsicSize(m_preset->size); 195 if (isProducingData()) 196 m_emitFrameTimer.startRepeating(1_s / frameRate); 195 197 } 196 198 -
trunk/Source/WebCore/testing/Internals.cpp
r260190 r260245 5003 5003 void Internals::observeMediaStreamTrack(MediaStreamTrack& track) 5004 5004 { 5005 if (m_trackSource) { 5006 m_trackSource->removeObserver(*this); 5007 m_trackSource->removeAudioSampleObserver(*this); 5008 5009 m_trackAudioSampleCount = 0; 5010 m_trackVideoSampleCount = 0; 5011 } 5012 5005 5013 m_trackSource = &track.source(); 5006 5014 m_trackSource->addObserver(*this);
Note: See TracChangeset
for help on using the changeset viewer.