Changing settings of a MediaStreamTrack clone should not alter the settings of the...
[WebKit-https.git] / Source / WebCore / platform / mediastream / mac / AVVideoCaptureSource.h
index f8dcd00..2a85ad4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(MEDIA_STREAM) && USE(AVFOUNDATION)
 
-#include "AVMediaCaptureSource.h"
+#include "IntSizeHash.h"
 #include "OrientationNotifier.h"
-
-OBJC_CLASS CALayer;
+#include "RealtimeVideoCaptureSource.h"
+#include <wtf/Lock.h>
+#include <wtf/text/StringHash.h>
+
+typedef struct opaqueCMSampleBuffer* CMSampleBufferRef;
+
+OBJC_CLASS AVCaptureConnection;
+OBJC_CLASS AVCaptureDevice;
+OBJC_CLASS AVCaptureDeviceFormat;
+OBJC_CLASS AVCaptureOutput;
+OBJC_CLASS AVCaptureSession;
+OBJC_CLASS AVCaptureVideoDataOutput;
 OBJC_CLASS AVFrameRateRange;
-
-typedef struct CGImage *CGImageRef;
-typedef const struct opaqueCMFormatDescription *CMFormatDescriptionRef;
-typedef struct opaqueCMSampleBuffer *CMSampleBufferRef;
+OBJC_CLASS NSError;
+OBJC_CLASS NSNotification;
+OBJC_CLASS WebCoreAVVideoCaptureSourceObserver;
 
 namespace WebCore {
 
-class FloatRect;
-class GraphicsContext;
-class PixelBufferConformerCV;
+class AVVideoPreset;
+class ImageTransferSessionVT;
 
-class AVVideoCaptureSource : public AVMediaCaptureSource, private OrientationNotifier::Observer {
+class AVVideoCaptureSource : public RealtimeVideoCaptureSource, private OrientationNotifier::Observer {
 public:
-    static CaptureSourceOrError create(const AtomicString&, const MediaConstraints*);
+    static CaptureSourceOrError create(String&& id, String&& hashSalt, const MediaConstraints*);
 
     WEBCORE_EXPORT static VideoCaptureFactory& factory();
 
-    int32_t width() const { return m_width; }
-    int32_t height() const { return m_height; }
+    enum class InterruptionReason { None, VideoNotAllowedInBackground, AudioInUse, VideoInUse, VideoNotAllowedInSideBySide };
+    void captureSessionBeginInterruption(RetainPtr<NSNotification>);
+    void captureSessionEndInterruption(RetainPtr<NSNotification>);
+    void deviceDisconnected(RetainPtr<NSNotification>);
+
+    AVCaptureSession* session() const { return m_session.get(); }
+
+    void captureSessionIsRunningDidChange(bool);
+    void captureSessionRuntimeError(RetainPtr<NSError>);
+    void captureOutputDidOutputSampleBufferFromConnection(AVCaptureOutput*, CMSampleBufferRef, AVCaptureConnection*);
+    void captureDeviceSuspendedDidChange();
 
 private:
-    AVVideoCaptureSource(AVCaptureDevice*, const AtomicString&);
+    AVVideoCaptureSource(AVCaptureDevice*, String&& id, String&& hashSalt);
     virtual ~AVVideoCaptureSource();
 
-    bool setupCaptureSession() final;
-    void shutdownCaptureSession() final;
-
-    void updateSettings(RealtimeMediaSourceSettings&) final;
+    void clearSession();
 
-    void applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>) final;
-    bool applySize(const IntSize&) final;
-    bool applyFrameRate(double) final;
-    bool setPreset(NSString*);
+    bool setupSession();
+    bool setupCaptureSession();
+    void shutdownCaptureSession();
 
+    const RealtimeMediaSourceCapabilities& capabilities() final;
+    const RealtimeMediaSourceSettings& settings() final;
+    void startProducingData() final;
+    void stopProducingData() final;
+    void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;
     void monitorOrientation(OrientationNotifier&) final;
+    void beginConfiguration() final;
+    void commitConfiguration() final;
+    bool isCaptureSource() const final { return true; }
+    CaptureDevice::DeviceType deviceType() const final { return CaptureDevice::DeviceType::Camera; }
+    bool interrupted() const final;
+
+    MediaSample::VideoRotation sampleRotation() const final { return m_sampleRotation; }
+    void setFrameRateWithPreset(double, RefPtr<VideoPreset>) final;
+    bool prefersPreset(VideoPreset&) final;
+    void generatePresets() final;
+    bool canResizeVideoFrames() const final { return true; }
+
+    void setSessionSizeAndFrameRate();
+    bool setPreset(NSString*);
     void computeSampleRotation();
-
-    bool isFrameRateSupported(double frameRate);
-
-    NSString *bestSessionPresetForVideoDimensions(std::optional<int> width, std::optional<int> height);
-    bool supportsSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>) final;
-
-    void initializeCapabilities(RealtimeMediaSourceCapabilities&) final;
-    void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&) final;
+    AVFrameRateRange* frameDurationForFrameRate(double);
 
     // OrientationNotifier::Observer API
     void orientationChanged(int orientation) final;
 
     bool setFrameRateConstraint(double minFrameRate, double maxFrameRate);
 
-    void captureOutputDidOutputSampleBufferFromConnection(AVCaptureOutput*, CMSampleBufferRef, AVCaptureConnection*) final;
-    void processNewFrame(RetainPtr<CMSampleBufferRef>, RetainPtr<AVCaptureConnection>);
+    void processNewFrame(Ref<MediaSample>&&);
     IntSize sizeForPreset(NSString*);
 
-    using VideoPresetMap = HashMap<String, IntSize>;
-    VideoPresetMap& videoPresets() { return m_supportedPresets; }
+    AVCaptureDevice* device() const { return m_device.get(); }
+
+#if !RELEASE_LOG_DISABLED
+    const char* logClassName() const override { return "AVVideoCaptureSource"; }
+#endif
 
-    RetainPtr<NSString> m_pendingPreset;
-    RetainPtr<CMSampleBufferRef> m_buffer;
+    RefPtr<MediaSample> m_buffer;
     RetainPtr<AVCaptureVideoDataOutput> m_videoOutput;
+    std::unique_ptr<ImageTransferSessionVT> m_imageTransferSession;
 
-    IntSize m_presetSize;
-    int32_t m_width { 0 };
-    int32_t m_height { 0 };
     int m_sensorOrientation { 0 };
     int m_deviceOrientation { 0 };
     MediaSample::VideoRotation m_sampleRotation { MediaSample::VideoRotation::None };
 
-    VideoPresetMap m_supportedPresets;
+    Optional<RealtimeMediaSourceSettings> m_currentSettings;
+    Optional<RealtimeMediaSourceCapabilities> m_capabilities;
+    RetainPtr<WebCoreAVVideoCaptureSourceObserver> m_objcObserver;
+    RetainPtr<AVCaptureSession> m_session;
+    RetainPtr<AVCaptureDevice> m_device;
+
+    Lock m_presetMutex;
+    RefPtr<AVVideoPreset> m_currentPreset;
+    IntSize m_currentSize;
+    double m_currentFrameRate;
+    InterruptionReason m_interruption { InterruptionReason::None };
+    int m_framesToDropAtStartup { 0 };
+    bool m_isRunning { false };
 };
 
 } // namespace WebCore
 
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::AVVideoPreset)
+    static bool isType(const WebCore::VideoPreset& preset) { return preset.type == WebCore::VideoPreset::VideoPresetType::AVCapture; }
+SPECIALIZE_TYPE_TRAITS_END()
+
 #endif // ENABLE(MEDIA_STREAM)