Changing settings of a MediaStreamTrack clone should not alter the settings of the...
[WebKit-https.git] / Source / WebCore / platform / mediastream / mac / AVVideoCaptureSource.h
1 /*
2  * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #if ENABLE(MEDIA_STREAM) && USE(AVFOUNDATION)
29
30 #include "IntSizeHash.h"
31 #include "OrientationNotifier.h"
32 #include "RealtimeVideoCaptureSource.h"
33 #include <wtf/Lock.h>
34 #include <wtf/text/StringHash.h>
35
36 typedef struct opaqueCMSampleBuffer* CMSampleBufferRef;
37
38 OBJC_CLASS AVCaptureConnection;
39 OBJC_CLASS AVCaptureDevice;
40 OBJC_CLASS AVCaptureDeviceFormat;
41 OBJC_CLASS AVCaptureOutput;
42 OBJC_CLASS AVCaptureSession;
43 OBJC_CLASS AVCaptureVideoDataOutput;
44 OBJC_CLASS AVFrameRateRange;
45 OBJC_CLASS NSError;
46 OBJC_CLASS NSNotification;
47 OBJC_CLASS WebCoreAVVideoCaptureSourceObserver;
48
49 namespace WebCore {
50
51 class AVVideoPreset;
52 class ImageTransferSessionVT;
53
54 class AVVideoCaptureSource : public RealtimeVideoCaptureSource, private OrientationNotifier::Observer {
55 public:
56     static CaptureSourceOrError create(String&& id, String&& hashSalt, const MediaConstraints*);
57
58     WEBCORE_EXPORT static VideoCaptureFactory& factory();
59
60     enum class InterruptionReason { None, VideoNotAllowedInBackground, AudioInUse, VideoInUse, VideoNotAllowedInSideBySide };
61     void captureSessionBeginInterruption(RetainPtr<NSNotification>);
62     void captureSessionEndInterruption(RetainPtr<NSNotification>);
63     void deviceDisconnected(RetainPtr<NSNotification>);
64
65     AVCaptureSession* session() const { return m_session.get(); }
66
67     void captureSessionIsRunningDidChange(bool);
68     void captureSessionRuntimeError(RetainPtr<NSError>);
69     void captureOutputDidOutputSampleBufferFromConnection(AVCaptureOutput*, CMSampleBufferRef, AVCaptureConnection*);
70     void captureDeviceSuspendedDidChange();
71
72 private:
73     AVVideoCaptureSource(AVCaptureDevice*, String&& id, String&& hashSalt);
74     virtual ~AVVideoCaptureSource();
75
76     void clearSession();
77
78     bool setupSession();
79     bool setupCaptureSession();
80     void shutdownCaptureSession();
81
82     const RealtimeMediaSourceCapabilities& capabilities() final;
83     const RealtimeMediaSourceSettings& settings() final;
84     void startProducingData() final;
85     void stopProducingData() final;
86     void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;
87     void monitorOrientation(OrientationNotifier&) final;
88     void beginConfiguration() final;
89     void commitConfiguration() final;
90     bool isCaptureSource() const final { return true; }
91     CaptureDevice::DeviceType deviceType() const final { return CaptureDevice::DeviceType::Camera; }
92     bool interrupted() const final;
93
94     MediaSample::VideoRotation sampleRotation() const final { return m_sampleRotation; }
95     void setFrameRateWithPreset(double, RefPtr<VideoPreset>) final;
96     bool prefersPreset(VideoPreset&) final;
97     void generatePresets() final;
98     bool canResizeVideoFrames() const final { return true; }
99
100     void setSessionSizeAndFrameRate();
101     bool setPreset(NSString*);
102     void computeSampleRotation();
103     AVFrameRateRange* frameDurationForFrameRate(double);
104
105     // OrientationNotifier::Observer API
106     void orientationChanged(int orientation) final;
107
108     bool setFrameRateConstraint(double minFrameRate, double maxFrameRate);
109
110     void processNewFrame(Ref<MediaSample>&&);
111     IntSize sizeForPreset(NSString*);
112
113     AVCaptureDevice* device() const { return m_device.get(); }
114
115 #if !RELEASE_LOG_DISABLED
116     const char* logClassName() const override { return "AVVideoCaptureSource"; }
117 #endif
118
119     RefPtr<MediaSample> m_buffer;
120     RetainPtr<AVCaptureVideoDataOutput> m_videoOutput;
121     std::unique_ptr<ImageTransferSessionVT> m_imageTransferSession;
122
123     int m_sensorOrientation { 0 };
124     int m_deviceOrientation { 0 };
125     MediaSample::VideoRotation m_sampleRotation { MediaSample::VideoRotation::None };
126
127     Optional<RealtimeMediaSourceSettings> m_currentSettings;
128     Optional<RealtimeMediaSourceCapabilities> m_capabilities;
129     RetainPtr<WebCoreAVVideoCaptureSourceObserver> m_objcObserver;
130     RetainPtr<AVCaptureSession> m_session;
131     RetainPtr<AVCaptureDevice> m_device;
132
133     Lock m_presetMutex;
134     RefPtr<AVVideoPreset> m_currentPreset;
135     IntSize m_currentSize;
136     double m_currentFrameRate;
137     InterruptionReason m_interruption { InterruptionReason::None };
138     int m_framesToDropAtStartup { 0 };
139     bool m_isRunning { false };
140 };
141
142 } // namespace WebCore
143
144 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::AVVideoPreset)
145     static bool isType(const WebCore::VideoPreset& preset) { return preset.type == WebCore::VideoPreset::VideoPresetType::AVCapture; }
146 SPECIALIZE_TYPE_TRAITS_END()
147
148 #endif // ENABLE(MEDIA_STREAM)