Changing settings of a MediaStreamTrack clone should not alter the settings of the...
[WebKit-https.git] / Source / WebCore / platform / mediastream / mac / AVVideoCaptureSource.h
index 502dadd..2a85ad4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 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
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef AVVideoCaptureSource_h
-#define AVVideoCaptureSource_h
+#pragma once
 
 #if ENABLE(MEDIA_STREAM) && USE(AVFOUNDATION)
 
-#include "AVMediaCaptureSource.h"
-
-OBJC_CLASS AVCaptureVideoPreviewLayer;
-
-typedef const struct opaqueCMFormatDescription *CMFormatDescriptionRef;
+#include "IntSizeHash.h"
+#include "OrientationNotifier.h"
+#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;
+OBJC_CLASS NSError;
+OBJC_CLASS NSNotification;
+OBJC_CLASS WebCoreAVVideoCaptureSourceObserver;
 
 namespace WebCore {
 
-class AVVideoCaptureSource : public AVMediaCaptureSource {
+class AVVideoPreset;
+class ImageTransferSessionVT;
+
+class AVVideoCaptureSource : public RealtimeVideoCaptureSource, private OrientationNotifier::Observer {
 public:
-    static RefPtr<AVMediaCaptureSource> create(AVCaptureDevice*, const AtomicString&, PassRefPtr<MediaConstraints>);
+    static CaptureSourceOrError create(String&& id, String&& hashSalt, const MediaConstraints*);
 
-    virtual RefPtr<RealtimeMediaSourceCapabilities> capabilities() const override;
-    virtual void captureOutputDidOutputSampleBufferFromConnection(AVCaptureOutput*, CMSampleBufferRef, AVCaptureConnection*) override;
-    
-    virtual int32_t width() const { return m_width; }
-    virtual int32_t height() const { return m_height; }
+    WEBCORE_EXPORT static VideoCaptureFactory& factory();
 
-    AVCaptureVideoPreviewLayer* previewLayer() { return m_videoPreviewLayer.get(); }
-    
-private:
-    AVVideoCaptureSource(AVCaptureDevice*, const AtomicString&, PassRefPtr<MediaConstraints>);
-    virtual ~AVVideoCaptureSource();
+    enum class InterruptionReason { None, VideoNotAllowedInBackground, AudioInUse, VideoInUse, VideoNotAllowedInSideBySide };
+    void captureSessionBeginInterruption(RetainPtr<NSNotification>);
+    void captureSessionEndInterruption(RetainPtr<NSNotification>);
+    void deviceDisconnected(RetainPtr<NSNotification>);
 
-    virtual void setupCaptureSession() override;
-    virtual void updateStates() override;
+    AVCaptureSession* session() const { return m_session.get(); }
 
-    bool applyConstraints(MediaConstraints*);
-    bool setFrameRateConstraint(float minFrameRate, float maxFrameRate);
+    void captureSessionIsRunningDidChange(bool);
+    void captureSessionRuntimeError(RetainPtr<NSError>);
+    void captureOutputDidOutputSampleBufferFromConnection(AVCaptureOutput*, CMSampleBufferRef, AVCaptureConnection*);
+    void captureDeviceSuspendedDidChange();
 
-    void calculateFramerate(CMSampleBufferRef);
+private:
+    AVVideoCaptureSource(AVCaptureDevice*, String&& id, String&& hashSalt);
+    virtual ~AVVideoCaptureSource();
 
-    RetainPtr<AVCaptureConnection> m_videoConnection;
-    RetainPtr<CMFormatDescriptionRef> m_videoFormatDescription;
-    RetainPtr<AVCaptureVideoPreviewLayer> m_videoPreviewLayer;
-    Vector<Float64> m_videoFrameTimeStamps;
-    Float64 m_frameRate;
-    int32_t m_width;
-    int32_t m_height;
+    void clearSession();
+
+    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();
+    AVFrameRateRange* frameDurationForFrameRate(double);
+
+    // OrientationNotifier::Observer API
+    void orientationChanged(int orientation) final;
+
+    bool setFrameRateConstraint(double minFrameRate, double maxFrameRate);
+
+    void processNewFrame(Ref<MediaSample>&&);
+    IntSize sizeForPreset(NSString*);
+
+    AVCaptureDevice* device() const { return m_device.get(); }
+
+#if !RELEASE_LOG_DISABLED
+    const char* logClassName() const override { return "AVVideoCaptureSource"; }
+#endif
+
+    RefPtr<MediaSample> m_buffer;
+    RetainPtr<AVCaptureVideoDataOutput> m_videoOutput;
+    std::unique_ptr<ImageTransferSessionVT> m_imageTransferSession;
+
+    int m_sensorOrientation { 0 };
+    int m_deviceOrientation { 0 };
+    MediaSample::VideoRotation m_sampleRotation { MediaSample::VideoRotation::None };
+
+    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
 
-#endif // ENABLE(MEDIA_STREAM)
+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 // AVVideoCaptureSource_h
+#endif // ENABLE(MEDIA_STREAM)