Title: [260064] trunk/Source/WebCore
Revision
260064
Author
[email protected]
Date
2020-04-14 02:36:06 -0700 (Tue, 14 Apr 2020)

Log Message

Add a timer to AVVideoCaptureSource to verify reception of frames
https://bugs.webkit.org/show_bug.cgi?id=210335

Reviewed by Eric Carlson.

Count the number of frames being captured.
Add a timer repeating every 3 seconds.
Timer starts/stops based on whether the session is running/is interrupted.
If the number of frames did not increase, fail the source.
Manually tested.

* platform/mediastream/RealtimeMediaSource.cpp:
(WebCore::RealtimeMediaSource::captureFailed):
Explicitly call stop() instead of just setting m_isProducingData.
This ensures we release all resources and that we may not restart capturing after captureFailed().
* platform/mediastream/mac/AVVideoCaptureSource.h:
* platform/mediastream/mac/AVVideoCaptureSource.mm:
(WebCore::AVVideoCaptureSource::AVVideoCaptureSource):
(WebCore::AVVideoCaptureSource::verifyIsCapturing):
(WebCore::AVVideoCaptureSource::updateVerifyCapturingTimer):
(WebCore::AVVideoCaptureSource::captureOutputDidOutputSampleBufferFromConnection):
(WebCore::AVVideoCaptureSource::captureSessionIsRunningDidChange):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (260063 => 260064)


--- trunk/Source/WebCore/ChangeLog	2020-04-14 09:30:15 UTC (rev 260063)
+++ trunk/Source/WebCore/ChangeLog	2020-04-14 09:36:06 UTC (rev 260064)
@@ -1,3 +1,28 @@
+2020-04-14  Youenn Fablet  <[email protected]>
+
+        Add a timer to AVVideoCaptureSource to verify reception of frames
+        https://bugs.webkit.org/show_bug.cgi?id=210335
+
+        Reviewed by Eric Carlson.
+
+        Count the number of frames being captured.
+        Add a timer repeating every 3 seconds.
+        Timer starts/stops based on whether the session is running/is interrupted.
+        If the number of frames did not increase, fail the source.
+        Manually tested.
+
+        * platform/mediastream/RealtimeMediaSource.cpp:
+        (WebCore::RealtimeMediaSource::captureFailed):
+        Explicitly call stop() instead of just setting m_isProducingData.
+        This ensures we release all resources and that we may not restart capturing after captureFailed().
+        * platform/mediastream/mac/AVVideoCaptureSource.h:
+        * platform/mediastream/mac/AVVideoCaptureSource.mm:
+        (WebCore::AVVideoCaptureSource::AVVideoCaptureSource):
+        (WebCore::AVVideoCaptureSource::verifyIsCapturing):
+        (WebCore::AVVideoCaptureSource::updateVerifyCapturingTimer):
+        (WebCore::AVVideoCaptureSource::captureOutputDidOutputSampleBufferFromConnection):
+        (WebCore::AVVideoCaptureSource::captureSessionIsRunningDidChange):
+
 2020-04-14  Commit Queue  <[email protected]>
 
         Unreviewed, reverting r260024.

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp (260063 => 260064)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp	2020-04-14 09:30:15 UTC (rev 260063)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp	2020-04-14 09:36:06 UTC (rev 260064)
@@ -266,9 +266,9 @@
 {
     ERROR_LOG_IF(m_logger, LOGIDENTIFIER);
 
-    m_isProducingData = false;
     m_captureDidFailed = true;
 
+    stop();
     forEachObserver([](auto& observer) {
         observer.sourceStopped();
     });

Modified: trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h (260063 => 260064)


--- trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h	2020-04-14 09:30:15 UTC (rev 260063)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h	2020-04-14 09:36:06 UTC (rev 260064)
@@ -30,6 +30,7 @@
 #include "IntSizeHash.h"
 #include "OrientationNotifier.h"
 #include "RealtimeVideoCaptureSource.h"
+#include "Timer.h"
 #include <wtf/Lock.h>
 #include <wtf/text/StringHash.h>
 
@@ -115,6 +116,9 @@
     const char* logClassName() const override { return "AVVideoCaptureSource"; }
 #endif
 
+    void updateVerifyCapturingTimer();
+    void verifyIsCapturing();
+
     RefPtr<MediaSample> m_buffer;
     RetainPtr<AVCaptureVideoDataOutput> m_videoOutput;
     std::unique_ptr<ImageTransferSessionVT> m_imageTransferSession;
@@ -133,9 +137,15 @@
     RefPtr<AVVideoPreset> m_currentPreset;
     IntSize m_currentSize;
     double m_currentFrameRate;
-    int m_framesToDropAtStartup { 0 };
     bool m_interrupted { false };
     bool m_isRunning { false };
+
+    static constexpr Seconds verifyCaptureInterval = 3_s;
+    static const uint64_t framesToDropWhenStarting = 4;
+
+    Timer m_verifyCapturingTimer;
+    uint64_t m_framesCount { 0 };
+    uint64_t m_lastFramesCount { 0 };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm (260063 => 260064)


--- trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm	2020-04-14 09:30:15 UTC (rev 260063)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm	2020-04-14 09:36:06 UTC (rev 260064)
@@ -129,6 +129,7 @@
     : RealtimeVideoCaptureSource(device.localizedName, WTFMove(id), WTFMove(hashSalt))
     , m_objcObserver(adoptNS([[WebCoreAVVideoCaptureSourceObserver alloc] initWithCallback:this]))
     , m_device(device)
+    , m_verifyCapturingTimer(*this, &AVVideoCaptureSource::verifyIsCapturing)
 {
     [m_device.get() addObserver:m_objcObserver.get() forKeyPath:@"suspended" options:NSKeyValueObservingOptionNew context:(void *)nil];
 }
@@ -150,6 +151,33 @@
     clearSession();
 }
 
+void AVVideoCaptureSource::verifyIsCapturing()
+{
+    ASSERT(m_isRunning);
+    if (m_lastFramesCount != m_framesCount) {
+        m_lastFramesCount = m_framesCount;
+        return;
+    }
+
+    RELEASE_LOG_ERROR(WebRTC, "AVVideoCaptureSource::verifyIsCapturing - no frame received in %d seconds, failing", static_cast<int>(m_verifyCapturingTimer.repeatInterval().value()));
+    captureFailed();
+}
+
+void AVVideoCaptureSource::updateVerifyCapturingTimer()
+{
+    if (!m_isRunning) {
+        m_verifyCapturingTimer.stop();
+        return;
+    }
+
+    if (m_verifyCapturingTimer.isActive())
+        return;
+
+    m_verifyCapturingTimer.startRepeating(verifyCaptureInterval);
+    m_framesCount = 0;
+    m_lastFramesCount = 0;
+}
+
 void AVVideoCaptureSource::clearSession()
 {
     ALWAYS_LOG_IF(loggerPtr(), LOGIDENTIFIER);
@@ -526,7 +554,7 @@
 
 void AVVideoCaptureSource::captureOutputDidOutputSampleBufferFromConnection(AVCaptureOutput*, CMSampleBufferRef sampleBuffer, AVCaptureConnection* captureConnection)
 {
-    if (m_framesToDropAtStartup && m_framesToDropAtStartup--)
+    if (++m_framesCount <= framesToDropWhenStarting)
         return;
 
     auto sample = MediaSampleAVFObjC::create(sampleBuffer, m_sampleRotation, [captureConnection isVideoMirrored]);
@@ -537,15 +565,14 @@
 
 void AVVideoCaptureSource::captureSessionIsRunningDidChange(bool state)
 {
-    scheduleDeferredTask([this, state] {
-        ALWAYS_LOG_IF(loggerPtr(), LOGIDENTIFIER, state);
+    scheduleDeferredTask([this, logIdentifier = LOGIDENTIFIER, state] {
+        ALWAYS_LOG_IF(loggerPtr(), logIdentifier, state);
         if ((state == m_isRunning) && (state == !muted()))
             return;
 
         m_isRunning = state;
-        if (m_isRunning)
-            m_framesToDropAtStartup = 4;
 
+        updateVerifyCapturingTimer();
         notifyMutedChange(!m_isRunning);
     });
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to