blob: 684f8730bd73f867f3eeafa783d72986692b1aed [file] [log] [blame]
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2010 The WebRTC project authors. All Rights Reserved.
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00009 */
10
henrike@webrtc.org28e20752013-07-10 00:45:36 +000011// Declaration of abstract class VideoCapturer
12
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#ifndef MEDIA_BASE_VIDEOCAPTURER_H_
14#define MEDIA_BASE_VIDEOCAPTURER_H_
henrike@webrtc.org28e20752013-07-10 00:45:36 +000015
pbosc7c26a02017-01-02 08:42:32 -080016#include <stdint.h>
17
andresp@webrtc.orgff689be2015-02-12 11:54:26 +000018#include <algorithm>
kwiberg686a8ef2016-02-26 03:00:35 -080019#include <memory>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000020#include <string>
21#include <vector>
22
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "media/base/videoadapter.h"
24#include "media/base/videobroadcaster.h"
25#include "media/base/videocommon.h"
26#include "media/base/videosourceinterface.h"
27#include "rtc_base/constructormagic.h"
28#include "rtc_base/criticalsection.h"
29#include "rtc_base/sigslot.h"
30#include "rtc_base/thread_checker.h"
31#include "rtc_base/timestampaligner.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032
nisseacd935b2016-11-11 03:55:13 -080033namespace webrtc {
34class VideoFrame;
35}
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036
37namespace cricket {
38
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039// Current state of the capturer.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040enum CaptureState {
41 CS_STOPPED, // The capturer has been stopped or hasn't started yet.
42 CS_STARTING, // The capturer is in the process of starting. Note, it may
43 // still fail to start.
44 CS_RUNNING, // The capturer has been started successfully and is now
45 // capturing.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046 CS_FAILED, // The capturer failed to start.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000047};
48
henrike@webrtc.org28e20752013-07-10 00:45:36 +000049// VideoCapturer is an abstract class that defines the interfaces for video
50// capturing. The subclasses implement the video capturer for various types of
51// capturers and various platforms.
52//
henrike@webrtc.orga7b98182014-02-21 15:51:43 +000053// The captured frames may need to be adapted (for example, cropping).
54// Video adaptation is built into and enabled by default. After a frame has
Magnus Jedvertc2320962015-08-21 11:40:30 +020055// been captured from the device, it is sent to the video adapter, then out to
Perfb45d172016-02-29 12:07:35 +010056// the sinks.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000057//
58// Programming model:
59// Create an object of a subclass of VideoCapturer
60// Initialize
61// SignalStateChange.connect()
Perfb45d172016-02-29 12:07:35 +010062// AddOrUpdateSink()
henrike@webrtc.org28e20752013-07-10 00:45:36 +000063// Find the capture format for Start() by either calling GetSupportedFormats()
64// and selecting one of the supported or calling GetBestCaptureFormat().
henrike@webrtc.orga7b98182014-02-21 15:51:43 +000065// video_adapter()->OnOutputFormatRequest(desired_encoding_format)
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066// Start()
67// GetCaptureFormat() optionally
68// Stop()
69//
70// Assumption:
71// The Start() and Stop() methods are called by a single thread (E.g., the
72// media engine thread). Hence, the VideoCapture subclasses dont need to be
73// thread safe.
74//
Pera5092412016-02-12 13:30:57 +010075class VideoCapturer : public sigslot::has_slots<>,
nisseacd935b2016-11-11 03:55:13 -080076 public rtc::VideoSourceInterface<webrtc::VideoFrame> {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000077 public:
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078 VideoCapturer();
Perfb45d172016-02-29 12:07:35 +010079
henrike@webrtc.org28e20752013-07-10 00:45:36 +000080 virtual ~VideoCapturer() {}
81
82 // Gets the id of the underlying device, which is available after the capturer
83 // is initialized. Can be used to determine if two capturers reference the
84 // same device.
85 const std::string& GetId() const { return id_; }
86
87 // Get the capture formats supported by the video capturer. The supported
88 // formats are non empty after the device has been opened successfully.
89 const std::vector<VideoFormat>* GetSupportedFormats() const;
90
91 // Get the best capture format for the desired format. The best format is the
92 // same as one of the supported formats except that the frame interval may be
93 // different. If the application asks for 16x9 and the camera does not support
94 // 16x9 HD or the application asks for 16x10, we find the closest 4x3 and then
95 // crop; Otherwise, we find what the application asks for. Note that we assume
96 // that for HD, the desired format is always 16x9. The subclasses can override
97 // the default implementation.
98 // Parameters
99 // desired: the input desired format. If desired.fourcc is not kAnyFourcc,
100 // the best capture format has the exactly same fourcc. Otherwise,
101 // the best capture format uses a fourcc in GetPreferredFourccs().
102 // best_format: the output of the best capture format.
103 // Return false if there is no such a best format, that is, the desired format
104 // is not supported.
105 virtual bool GetBestCaptureFormat(const VideoFormat& desired,
106 VideoFormat* best_format);
107
108 // TODO(hellner): deprecate (make private) the Start API in favor of this one.
109 // Also remove CS_STARTING as it is implied by the return
110 // value of StartCapturing().
111 bool StartCapturing(const VideoFormat& capture_format);
112 // Start the video capturer with the specified capture format.
113 // Parameter
114 // capture_format: The caller got this parameter by either calling
115 // GetSupportedFormats() and selecting one of the supported
116 // or calling GetBestCaptureFormat().
117 // Return
118 // CS_STARTING: The capturer is trying to start. Success or failure will
119 // be notified via the |SignalStateChange| callback.
120 // CS_RUNNING: if the capturer is started and capturing.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000121 // CS_FAILED: if the capturer failes to start..
122 // CS_NO_DEVICE: if the capturer has no device and fails to start.
123 virtual CaptureState Start(const VideoFormat& capture_format) = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000124
125 // Get the current capture format, which is set by the Start() call.
126 // Note that the width and height of the captured frames may differ from the
127 // capture format. For example, the capture format is HD but the captured
128 // frames may be smaller than HD.
129 const VideoFormat* GetCaptureFormat() const {
130 return capture_format_.get();
131 }
132
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000133 // Stop the video capturer.
134 virtual void Stop() = 0;
135 // Check if the video capturer is running.
136 virtual bool IsRunning() = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000137 CaptureState capture_state() const {
138 return capture_state_;
139 }
140
nisse47ac4622016-05-25 08:47:01 -0700141 virtual bool apply_rotation() { return apply_rotation_; }
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000142
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000143 // Returns true if the capturer is screencasting. This can be used to
144 // implement screencast specific behavior.
145 virtual bool IsScreencast() const = 0;
146
147 // Caps the VideoCapturer's format according to max_format. It can e.g. be
148 // used to prevent cameras from capturing at a resolution or framerate that
149 // the capturer is capable of but not performing satisfactorily at.
150 // The capping is an upper bound for each component of the capturing format.
151 // The fourcc component is ignored.
152 void ConstrainSupportedFormats(const VideoFormat& max_format);
153
154 void set_enable_camera_list(bool enable_camera_list) {
155 enable_camera_list_ = enable_camera_list;
156 }
157 bool enable_camera_list() {
158 return enable_camera_list_;
159 }
mallinath@webrtc.org1b15f422013-09-06 22:56:28 +0000160
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000161 // Signal all capture state changes that are not a direct result of calling
162 // Start().
163 sigslot::signal2<VideoCapturer*, CaptureState> SignalStateChange;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000164
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000165 // If true, run video adaptation. By default, video adaptation is enabled
166 // and users must call video_adapter()->OnOutputFormatRequest()
167 // to receive frames.
168 bool enable_video_adapter() const { return enable_video_adapter_; }
169 void set_enable_video_adapter(bool enable_video_adapter) {
170 enable_video_adapter_ = enable_video_adapter;
171 }
172
nissefcc640f2016-04-01 01:10:42 -0700173 bool GetInputSize(int* width, int* height);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000174
Pera5092412016-02-12 13:30:57 +0100175 // Implements VideoSourceInterface
nisseacd935b2016-11-11 03:55:13 -0800176 void AddOrUpdateSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink,
Pera5092412016-02-12 13:30:57 +0100177 const rtc::VideoSinkWants& wants) override;
nisseacd935b2016-11-11 03:55:13 -0800178 void RemoveSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) override;
Pera5092412016-02-12 13:30:57 +0100179
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000180 protected:
Pera5092412016-02-12 13:30:57 +0100181 // OnSinkWantsChanged can be overridden to change the default behavior
182 // when a sink changes its VideoSinkWants by calling AddOrUpdateSink.
183 virtual void OnSinkWantsChanged(const rtc::VideoSinkWants& wants);
184
nisse47ac4622016-05-25 08:47:01 -0700185 // Reports the appropriate frame size after adaptation. Returns true
186 // if a frame is wanted. Returns false if there are no interested
187 // sinks, or if the VideoAdapter decides to drop the frame.
nisse191b3592016-06-22 08:36:53 -0700188
189 // This function also implements timestamp translation/filtering.
190 // |camera_time_ns| is the camera's timestamp for the captured
191 // frame; it is expected to have good accuracy, but it may use an
192 // arbitrary epoch and a small possibly free-running with a frequency
193 // slightly different from the system clock. |system_time_us| is the
194 // monotonic system time (in the same scale as rtc::TimeMicros) when
195 // the frame was captured; the application is expected to read the
196 // system time as soon as possible after frame capture, but it may
197 // suffer scheduling jitter or poor system clock resolution. The
198 // output |translated_camera_time_us| is a combined timestamp,
199 // taking advantage of the supposedly higher accuracy in the camera
200 // timestamp, but using the same epoch and frequency as system time.
nisse47ac4622016-05-25 08:47:01 -0700201 bool AdaptFrame(int width,
202 int height,
nisse191b3592016-06-22 08:36:53 -0700203 int64_t camera_time_us,
204 int64_t system_time_us,
nisse47ac4622016-05-25 08:47:01 -0700205 int* out_width,
206 int* out_height,
207 int* crop_width,
208 int* crop_height,
209 int* crop_x,
nisse191b3592016-06-22 08:36:53 -0700210 int* crop_y,
211 int64_t* translated_camera_time_us);
nisse47ac4622016-05-25 08:47:01 -0700212
nisse47ac4622016-05-25 08:47:01 -0700213 // Called when a frame has been captured and converted to a
214 // VideoFrame. OnFrame can be called directly by an implementation
215 // that does not use SignalFrameCaptured or OnFrameCaptured. The
216 // orig_width and orig_height are used only to produce stats.
nisseacd935b2016-11-11 03:55:13 -0800217 void OnFrame(const webrtc::VideoFrame& frame,
218 int orig_width,
219 int orig_height);
Pera5092412016-02-12 13:30:57 +0100220
Per766ad3b2016-04-05 15:23:49 +0200221 VideoAdapter* video_adapter() { return &video_adapter_; }
perkj2d5f0912016-02-29 00:04:41 -0800222
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000223 void SetCaptureState(CaptureState state);
224
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000225 // subclasses override this virtual method to provide a vector of fourccs, in
226 // order of preference, that are expected by the media engine.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200227 virtual bool GetPreferredFourccs(std::vector<uint32_t>* fourccs) = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000228
229 // mutators to set private attributes
230 void SetId(const std::string& id) {
231 id_ = id;
232 }
233
234 void SetCaptureFormat(const VideoFormat* format) {
235 capture_format_.reset(format ? new VideoFormat(*format) : NULL);
236 }
237
238 void SetSupportedFormats(const std::vector<VideoFormat>& formats);
239
240 private:
241 void Construct();
242 // Get the distance between the desired format and the supported format.
243 // Return the max distance if they mismatch. See the implementation for
244 // details.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200245 int64_t GetFormatDistance(const VideoFormat& desired,
246 const VideoFormat& supported);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000247
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248 // Updates filtered_supported_formats_ so that it contains the formats in
249 // supported_formats_ that fulfill all applied restrictions.
250 void UpdateFilteredSupportedFormats();
251 // Returns true if format doesn't fulfill all applied restrictions.
252 bool ShouldFilterFormat(const VideoFormat& format) const;
253
nisse47ac4622016-05-25 08:47:01 -0700254 void UpdateInputSize(int width, int height);
buildbot@webrtc.org0b53bd22014-05-06 17:12:36 +0000255
Perfb45d172016-02-29 12:07:35 +0100256 rtc::ThreadChecker thread_checker_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000257 std::string id_;
258 CaptureState capture_state_;
kwiberg686a8ef2016-02-26 03:00:35 -0800259 std::unique_ptr<VideoFormat> capture_format_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000260 std::vector<VideoFormat> supported_formats_;
kwiberg686a8ef2016-02-26 03:00:35 -0800261 std::unique_ptr<VideoFormat> max_format_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262 std::vector<VideoFormat> filtered_supported_formats_;
263
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000264 bool enable_camera_list_;
265 int scaled_width_; // Current output size from ComputeScale.
266 int scaled_height_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000267
Pera5092412016-02-12 13:30:57 +0100268 rtc::VideoBroadcaster broadcaster_;
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000269 bool enable_video_adapter_;
Per766ad3b2016-04-05 15:23:49 +0200270 VideoAdapter video_adapter_;
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000271
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000272 rtc::CriticalSection frame_stats_crit_;
nissefcc640f2016-04-01 01:10:42 -0700273 // The captured frame size before potential adapation.
danilchapa37de392017-09-09 04:17:22 -0700274 bool input_size_valid_ RTC_GUARDED_BY(frame_stats_crit_) = false;
275 int input_width_ RTC_GUARDED_BY(frame_stats_crit_);
276 int input_height_ RTC_GUARDED_BY(frame_stats_crit_);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000277
nissef5297a02016-09-30 01:34:27 -0700278 // Whether capturer should apply rotation to the frame before
279 // passing it on to the registered sinks.
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000280 bool apply_rotation_;
281
nisse191b3592016-06-22 08:36:53 -0700282 // State for the timestamp translation.
283 rtc::TimestampAligner timestamp_aligner_;
henrikg3c089d72015-09-16 05:37:44 -0700284 RTC_DISALLOW_COPY_AND_ASSIGN(VideoCapturer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000285};
286
287} // namespace cricket
288
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200289#endif // MEDIA_BASE_VIDEOCAPTURER_H_