Modified: trunk/Source/WebCore/ChangeLog (218646 => 218647)
--- trunk/Source/WebCore/ChangeLog 2017-06-21 20:52:20 UTC (rev 218646)
+++ trunk/Source/WebCore/ChangeLog 2017-06-21 21:06:21 UTC (rev 218647)
@@ -1,5 +1,26 @@
2017-06-21 Youenn Fablet <[email protected]>
+ Fix AVVideoCaptureSource frameRate setter and getter
+ https://bugs.webkit.org/show_bug.cgi?id=173637
+
+ Reviewed by Eric Carlson.
+
+ Covered by manual testing.
+
+ Using activeVideoMaxFrameDuration to get the frame rate.
+ Setting the frame rate according the given vale if in the allowed range.
+
+ * platform/mediastream/mac/AVVideoCaptureSource.h:
+ * platform/mediastream/mac/AVVideoCaptureSource.mm:
+ (WebCore::AVVideoCaptureSource::updateSettings):
+ (WebCore::AVVideoCaptureSource::applyFrameRate):
+ (WebCore::AVVideoCaptureSource::applySizeAndFrameRate):
+ (WebCore::AVVideoCaptureSource::shutdownCaptureSession):
+ (WebCore::AVVideoCaptureSource::processNewFrame):
+ (WebCore::AVVideoCaptureSource::updateFramerate): Deleted.
+
+2017-06-21 Youenn Fablet <[email protected]>
+
Refresh libwebrtc code up to a87675d4a160e2c49c3e754cd9ca291d6c8f36ae
https://bugs.webkit.org/show_bug.cgi?id=173602
Modified: trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h (218646 => 218647)
--- trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h 2017-06-21 20:52:20 UTC (rev 218646)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h 2017-06-21 21:06:21 UTC (rev 218647)
@@ -69,6 +69,8 @@
void monitorOrientation(OrientationNotifier&) final;
void computeSampleRotation();
+ bool isFrameRateSupported(double frameRate);
+
NSString *bestSessionPresetForVideoDimensions(std::optional<int> width, std::optional<int> height) const;
bool supportsSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>) final;
@@ -80,8 +82,6 @@
bool setFrameRateConstraint(double minFrameRate, double maxFrameRate);
- bool updateFramerate(CMSampleBufferRef);
-
void captureOutputDidOutputSampleBufferFromConnection(AVCaptureOutput*, CMSampleBufferRef, AVCaptureConnection*) final;
void processNewFrame(RetainPtr<CMSampleBufferRef>, RetainPtr<AVCaptureConnection>);
@@ -92,8 +92,6 @@
std::unique_ptr<PixelBufferConformerCV> m_pixelBufferConformer;
- Vector<Float64> m_videoFrameTimeStamps;
- Float64 m_frameRate { 0 };
int32_t m_width { 0 };
int32_t m_height { 0 };
int m_sensorOrientation { 0 };
Modified: trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm (218646 => 218647)
--- trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm 2017-06-21 20:52:20 UTC (rev 218646)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm 2017-06-21 21:06:21 UTC (rev 218647)
@@ -257,8 +257,10 @@
settings.setFacingMode(RealtimeMediaSourceSettings::Environment);
else
settings.setFacingMode(RealtimeMediaSourceSettings::Unknown);
-
- settings.setFrameRate(m_frameRate);
+
+ // FIXME: Observe frame rate changes.
+ auto maxFrameDuration = [device() activeVideoMaxFrameDuration];
+ settings.setFrameRate(maxFrameDuration.timescale / maxFrameDuration.value);
settings.setWidth(m_width);
settings.setHeight(m_height);
settings.setAspectRatio(static_cast<float>(m_width) / m_height);
@@ -326,15 +328,16 @@
bool AVVideoCaptureSource::applyFrameRate(double rate)
{
+ double epsilon = 0.00001;
AVFrameRateRangeType *bestFrameRateRange = nil;
for (AVFrameRateRangeType *frameRateRange in [[device() activeFormat] videoSupportedFrameRateRanges]) {
- if (rate >= [frameRateRange minFrameRate] && rate <= [frameRateRange maxFrameRate]) {
+ if (rate + epsilon >= [frameRateRange minFrameRate] && rate - epsilon <= [frameRateRange maxFrameRate]) {
if (!bestFrameRateRange || CMTIME_COMPARE_INLINE([frameRateRange minFrameDuration], >, [bestFrameRateRange minFrameDuration]))
bestFrameRateRange = frameRateRange;
}
}
- if (!bestFrameRateRange) {
+ if (!bestFrameRateRange || !isFrameRateSupported(rate)) {
LOG(Media, "AVVideoCaptureSource::applyFrameRate(%p), frame rate %f not supported by video device", this, rate);
return false;
}
@@ -342,7 +345,13 @@
NSError *error = nil;
@try {
if ([device() lockForConfiguration:&error]) {
- [device() setActiveVideoMinFrameDuration:[bestFrameRateRange minFrameDuration]];
+ if (bestFrameRateRange.minFrameRate == bestFrameRateRange.maxFrameRate) {
+ [device() setActiveVideoMinFrameDuration:[bestFrameRateRange minFrameDuration]];
+ [device() setActiveVideoMaxFrameDuration:[bestFrameRateRange maxFrameDuration]];
+ } else {
+ [device() setActiveVideoMinFrameDuration: CMTimeMake(1, rate)];
+ [device() setActiveVideoMaxFrameDuration: CMTimeMake(1, rate)];
+ }
[device() unlockForConfiguration];
}
} @catch(NSException *exception) {
@@ -361,7 +370,8 @@
void AVVideoCaptureSource::applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate)
{
- setPreset(bestSessionPresetForVideoDimensions(WTFMove(width), WTFMove(height)));
+ if (width || height)
+ setPreset(bestSessionPresetForVideoDimensions(WTFMove(width), WTFMove(height)));
if (frameRate)
applyFrameRate(frameRate.value());
@@ -451,32 +461,10 @@
{
m_buffer = nullptr;
m_lastImage = nullptr;
- m_videoFrameTimeStamps.clear();
- m_frameRate = 0;
m_width = 0;
m_height = 0;
}
-bool AVVideoCaptureSource::updateFramerate(CMSampleBufferRef sampleBuffer)
-{
- CMTime sampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
- if (!CMTIME_IS_NUMERIC(sampleTime))
- return false;
-
- Float64 frameTime = CMTimeGetSeconds(sampleTime);
- Float64 _oneSecondAgo_ = frameTime - 1;
-
- m_videoFrameTimeStamps.append(frameTime);
-
- while (m_videoFrameTimeStamps[0] < oneSecondAgo)
- m_videoFrameTimeStamps.remove(0);
-
- Float64 frameRate = m_frameRate;
- m_frameRate = (m_frameRate + m_videoFrameTimeStamps.size()) / 2;
-
- return frameRate != m_frameRate;
-}
-
void AVVideoCaptureSource::monitorOrientation(OrientationNotifier& notifier)
{
#if PLATFORM(IOS)
@@ -529,7 +517,6 @@
if (!formatDescription)
return;
- updateFramerate(sampleBuffer.get());
m_buffer = sampleBuffer;
m_lastImage = nullptr;
@@ -581,6 +568,16 @@
return nil;
}
+bool AVVideoCaptureSource::isFrameRateSupported(double frameRate)
+{
+ double epsilon = 0.00001;
+ for (AVFrameRateRangeType *range in [[device() activeFormat] videoSupportedFrameRateRanges]) {
+ if (frameRate + epsilon >= range.minFrameRate && frameRate - epsilon <= range.maxFrameRate)
+ return true;
+ }
+ return false;
+}
+
bool AVVideoCaptureSource::supportsSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate)
{
if (!height && !width && !frameRate)
@@ -592,13 +589,7 @@
if (!frameRate)
return true;
- int rate = static_cast<int>(frameRate.value());
- for (AVFrameRateRangeType *range in [[device() activeFormat] videoSupportedFrameRateRanges]) {
- if (rate >= static_cast<int>(range.minFrameRate) && rate <= static_cast<int>(range.maxFrameRate))
- return true;
- }
-
- return false;
+ return isFrameRateSupported(frameRate.value());
}
} // namespace WebCore