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);
});
}