• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
4  *  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.
9  */
10 
11 #ifndef VIDEO_VIDEO_STREAM_ENCODER_H_
12 #define VIDEO_VIDEO_STREAM_ENCODER_H_
13 
14 #include <atomic>
15 #include <map>
16 #include <memory>
17 #include <string>
18 #include <vector>
19 
20 #include "absl/container/inlined_vector.h"
21 #include "api/adaptation/resource.h"
22 #include "api/field_trials_view.h"
23 #include "api/rtp_sender_interface.h"
24 #include "api/sequence_checker.h"
25 #include "api/task_queue/pending_task_safety_flag.h"
26 #include "api/units/data_rate.h"
27 #include "api/video/encoded_image.h"
28 #include "api/video/video_bitrate_allocator.h"
29 #include "api/video/video_rotation.h"
30 #include "api/video/video_sink_interface.h"
31 #include "api/video/video_stream_encoder_settings.h"
32 #include "api/video_codecs/video_codec.h"
33 #include "api/video_codecs/video_encoder.h"
34 #include "call/adaptation/adaptation_constraint.h"
35 #include "call/adaptation/resource_adaptation_processor.h"
36 #include "call/adaptation/resource_adaptation_processor_interface.h"
37 #include "call/adaptation/video_source_restrictions.h"
38 #include "call/adaptation/video_stream_input_state_provider.h"
39 #include "modules/video_coding/utility/frame_dropper.h"
40 #include "modules/video_coding/utility/qp_parser.h"
41 #include "rtc_base/experiments/rate_control_settings.h"
42 #include "rtc_base/numerics/exp_filter.h"
43 #include "rtc_base/race_checker.h"
44 #include "rtc_base/rate_statistics.h"
45 #include "rtc_base/task_queue.h"
46 #include "rtc_base/thread_annotations.h"
47 #include "system_wrappers/include/clock.h"
48 #include "video/adaptation/video_stream_encoder_resource_manager.h"
49 #include "video/encoder_bitrate_adjuster.h"
50 #include "video/frame_cadence_adapter.h"
51 #include "video/frame_encode_metadata_writer.h"
52 #include "video/video_source_sink_controller.h"
53 #include "video/video_stream_encoder_interface.h"
54 #include "video/video_stream_encoder_observer.h"
55 
56 namespace webrtc {
57 
58 // VideoStreamEncoder represent a video encoder that accepts raw video frames as
59 // input and produces an encoded bit stream.
60 // Usage:
61 //  Instantiate.
62 //  Call SetSink.
63 //  Call SetSource.
64 //  Call ConfigureEncoder with the codec settings.
65 //  Call Stop() when done.
66 class VideoStreamEncoder : public VideoStreamEncoderInterface,
67                            private EncodedImageCallback,
68                            public VideoSourceRestrictionsListener {
69  public:
70   // TODO(bugs.webrtc.org/12000): Reporting of VideoBitrateAllocation is being
71   // deprecated. Instead VideoLayersAllocation should be reported.
72   enum class BitrateAllocationCallbackType {
73     kVideoBitrateAllocation,
74     kVideoBitrateAllocationWhenScreenSharing,
75     kVideoLayersAllocation
76   };
77   VideoStreamEncoder(
78       Clock* clock,
79       uint32_t number_of_cores,
80       VideoStreamEncoderObserver* encoder_stats_observer,
81       const VideoStreamEncoderSettings& settings,
82       std::unique_ptr<OveruseFrameDetector> overuse_detector,
83       std::unique_ptr<FrameCadenceAdapterInterface> frame_cadence_adapter,
84       std::unique_ptr<webrtc::TaskQueueBase, webrtc::TaskQueueDeleter>
85           encoder_queue,
86       BitrateAllocationCallbackType allocation_cb_type,
87       const FieldTrialsView& field_trials,
88       webrtc::VideoEncoderFactory::EncoderSelectorInterface* encoder_selector =
89           nullptr);
90   ~VideoStreamEncoder() override;
91 
92   VideoStreamEncoder(const VideoStreamEncoder&) = delete;
93   VideoStreamEncoder& operator=(const VideoStreamEncoder&) = delete;
94 
95   void AddAdaptationResource(rtc::scoped_refptr<Resource> resource) override;
96   std::vector<rtc::scoped_refptr<Resource>> GetAdaptationResources() override;
97 
98   void SetSource(rtc::VideoSourceInterface<VideoFrame>* source,
99                  const DegradationPreference& degradation_preference) override;
100 
101   void SetSink(EncoderSink* sink, bool rotation_applied) override;
102 
103   // TODO(perkj): Can we remove VideoCodec.startBitrate ?
104   void SetStartBitrate(int start_bitrate_bps) override;
105 
106   void SetFecControllerOverride(
107       FecControllerOverride* fec_controller_override) override;
108 
109   void ConfigureEncoder(VideoEncoderConfig config,
110                         size_t max_data_payload_length) override;
111   void ConfigureEncoder(VideoEncoderConfig config,
112                         size_t max_data_payload_length,
113                         SetParametersCallback callback) override;
114 
115   // Permanently stop encoding. After this method has returned, it is
116   // guaranteed that no encoded frames will be delivered to the sink.
117   void Stop() override;
118 
119   void SendKeyFrame(const std::vector<VideoFrameType>& layers = {}) override;
120 
121   void OnLossNotification(
122       const VideoEncoder::LossNotification& loss_notification) override;
123 
124   void OnBitrateUpdated(DataRate target_bitrate,
125                         DataRate stable_target_bitrate,
126                         DataRate target_headroom,
127                         uint8_t fraction_lost,
128                         int64_t round_trip_time_ms,
129                         double cwnd_reduce_ratio) override;
130 
131   DataRate UpdateTargetBitrate(DataRate target_bitrate,
132                                double cwnd_reduce_ratio);
133 
134  protected:
135   // Used for testing. For example the `ScalingObserverInterface` methods must
136   // be called on `encoder_queue_`.
encoder_queue()137   TaskQueueBase* encoder_queue() { return encoder_queue_.Get(); }
138 
139   void OnVideoSourceRestrictionsUpdated(
140       VideoSourceRestrictions restrictions,
141       const VideoAdaptationCounters& adaptation_counters,
142       rtc::scoped_refptr<Resource> reason,
143       const VideoSourceRestrictions& unfiltered_restrictions) override;
144 
145   // Used for injected test resources.
146   // TODO(eshr): Move all adaptation tests out of VideoStreamEncoder tests.
147   void InjectAdaptationResource(rtc::scoped_refptr<Resource> resource,
148                                 VideoAdaptationReason reason);
149   void InjectAdaptationConstraint(AdaptationConstraint* adaptation_constraint);
150 
151   void AddRestrictionsListenerForTesting(
152       VideoSourceRestrictionsListener* restrictions_listener);
153   void RemoveRestrictionsListenerForTesting(
154       VideoSourceRestrictionsListener* restrictions_listener);
155 
156  private:
157   class CadenceCallback : public FrameCadenceAdapterInterface::Callback {
158    public:
CadenceCallback(VideoStreamEncoder & video_stream_encoder)159     explicit CadenceCallback(VideoStreamEncoder& video_stream_encoder)
160         : video_stream_encoder_(video_stream_encoder) {}
161     // FrameCadenceAdapterInterface::Callback overrides.
OnFrame(Timestamp post_time,int frames_scheduled_for_processing,const VideoFrame & frame)162     void OnFrame(Timestamp post_time,
163                  int frames_scheduled_for_processing,
164                  const VideoFrame& frame) override {
165       video_stream_encoder_.OnFrame(post_time, frames_scheduled_for_processing,
166                                     frame);
167     }
OnDiscardedFrame()168     void OnDiscardedFrame() override {
169       video_stream_encoder_.OnDiscardedFrame();
170     }
RequestRefreshFrame()171     void RequestRefreshFrame() override {
172       video_stream_encoder_.RequestRefreshFrame();
173     }
174 
175    private:
176     VideoStreamEncoder& video_stream_encoder_;
177   };
178 
179   class VideoFrameInfo {
180    public:
VideoFrameInfo(int width,int height,bool is_texture)181     VideoFrameInfo(int width, int height, bool is_texture)
182         : width(width), height(height), is_texture(is_texture) {}
183     int width;
184     int height;
185     bool is_texture;
pixel_count()186     int pixel_count() const { return width * height; }
187   };
188 
189   struct EncoderRateSettings {
190     EncoderRateSettings();
191     EncoderRateSettings(const VideoBitrateAllocation& bitrate,
192                         double framerate_fps,
193                         DataRate bandwidth_allocation,
194                         DataRate encoder_target,
195                         DataRate stable_encoder_target);
196     bool operator==(const EncoderRateSettings& rhs) const;
197     bool operator!=(const EncoderRateSettings& rhs) const;
198 
199     VideoEncoder::RateControlParameters rate_control;
200     // This is the scalar target bitrate before the VideoBitrateAllocator, i.e.
201     // the `target_bitrate` argument of the OnBitrateUpdated() method. This is
202     // needed because the bitrate allocator may truncate the total bitrate and a
203     // later call to the same allocator instance, e.g.
204     // |using last_encoder_rate_setings_->bitrate.get_sum_bps()|, may trick it
205     // into thinking the available bitrate has decreased since the last call.
206     DataRate encoder_target;
207     DataRate stable_encoder_target;
208   };
209 
210   class DegradationPreferenceManager;
211 
212   void ReconfigureEncoder() RTC_RUN_ON(&encoder_queue_);
213   void OnEncoderSettingsChanged() RTC_RUN_ON(&encoder_queue_);
214   void OnFrame(Timestamp post_time,
215                int frames_scheduled_for_processing,
216                const VideoFrame& video_frame);
217   void OnDiscardedFrame();
218   void RequestRefreshFrame();
219 
220   void MaybeEncodeVideoFrame(const VideoFrame& frame,
221                              int64_t time_when_posted_in_ms);
222 
223   void EncodeVideoFrame(const VideoFrame& frame,
224                         int64_t time_when_posted_in_ms);
225   // Indicates whether frame should be dropped because the pixel count is too
226   // large for the current bitrate configuration.
227   bool DropDueToSize(uint32_t pixel_count) const RTC_RUN_ON(&encoder_queue_);
228 
229   // Implements EncodedImageCallback.
230   EncodedImageCallback::Result OnEncodedImage(
231       const EncodedImage& encoded_image,
232       const CodecSpecificInfo* codec_specific_info) override;
233 
234   void OnDroppedFrame(EncodedImageCallback::DropReason reason) override;
235 
236   bool EncoderPaused() const;
237   void TraceFrameDropStart();
238   void TraceFrameDropEnd();
239 
240   // Returns a copy of `rate_settings` with the `bitrate` field updated using
241   // the current VideoBitrateAllocator.
242   EncoderRateSettings UpdateBitrateAllocation(
243       const EncoderRateSettings& rate_settings) RTC_RUN_ON(&encoder_queue_);
244 
245   uint32_t GetInputFramerateFps() RTC_RUN_ON(&encoder_queue_);
246   void SetEncoderRates(const EncoderRateSettings& rate_settings)
247       RTC_RUN_ON(&encoder_queue_);
248 
249   void RunPostEncode(const EncodedImage& encoded_image,
250                      int64_t time_sent_us,
251                      int temporal_index,
252                      DataSize frame_size);
253   void ReleaseEncoder() RTC_RUN_ON(&encoder_queue_);
254   // After calling this function `resource_adaptation_processor_` will be null.
255   void ShutdownResourceAdaptationQueue();
256 
257   void CheckForAnimatedContent(const VideoFrame& frame,
258                                int64_t time_when_posted_in_ms)
259       RTC_RUN_ON(&encoder_queue_);
260 
261   void RequestEncoderSwitch() RTC_RUN_ON(&encoder_queue_);
262 
263   // Augments an EncodedImage received from an encoder with parsable
264   // information.
265   EncodedImage AugmentEncodedImage(
266       const EncodedImage& encoded_image,
267       const CodecSpecificInfo* codec_specific_info);
268 
269   const FieldTrialsView& field_trials_;
270   TaskQueueBase* const worker_queue_;
271 
272   const int number_of_cores_;
273 
274   EncoderSink* sink_;
275   const VideoStreamEncoderSettings settings_;
276   const BitrateAllocationCallbackType allocation_cb_type_;
277   const RateControlSettings rate_control_settings_;
278 
279   webrtc::VideoEncoderFactory::EncoderSelectorInterface* const
280       encoder_selector_from_constructor_;
281   std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface> const
282       encoder_selector_from_factory_;
283   // Pointing to either encoder_selector_from_constructor_ or
284   // encoder_selector_from_factory_ but can be nullptr.
285   VideoEncoderFactory::EncoderSelectorInterface* const encoder_selector_;
286 
287   VideoStreamEncoderObserver* const encoder_stats_observer_;
288   // Adapter that avoids public inheritance of the cadence adapter's callback
289   // interface.
290   CadenceCallback cadence_callback_;
291   // Frame cadence encoder adapter. Frames enter this adapter first, and it then
292   // forwards them to our OnFrame method.
293   std::unique_ptr<FrameCadenceAdapterInterface> frame_cadence_adapter_
294       RTC_GUARDED_BY(&encoder_queue_) RTC_PT_GUARDED_BY(&encoder_queue_);
295 
296   VideoEncoderConfig encoder_config_ RTC_GUARDED_BY(&encoder_queue_);
297   std::unique_ptr<VideoEncoder> encoder_ RTC_GUARDED_BY(&encoder_queue_)
298       RTC_PT_GUARDED_BY(&encoder_queue_);
299   bool encoder_initialized_;
300   std::unique_ptr<VideoBitrateAllocator> rate_allocator_
301       RTC_GUARDED_BY(&encoder_queue_) RTC_PT_GUARDED_BY(&encoder_queue_);
302   int max_framerate_ RTC_GUARDED_BY(&encoder_queue_);
303 
304   // Set when ConfigureEncoder has been called in order to lazy reconfigure the
305   // encoder on the next frame.
306   bool pending_encoder_reconfiguration_ RTC_GUARDED_BY(&encoder_queue_);
307   // Set when configuration must create a new encoder object, e.g.,
308   // because of a codec change.
309   bool pending_encoder_creation_ RTC_GUARDED_BY(&encoder_queue_);
310   absl::InlinedVector<SetParametersCallback, 2> encoder_configuration_callbacks_
311       RTC_GUARDED_BY(&encoder_queue_);
312 
313   absl::optional<VideoFrameInfo> last_frame_info_
314       RTC_GUARDED_BY(&encoder_queue_);
315   int crop_width_ RTC_GUARDED_BY(&encoder_queue_);
316   int crop_height_ RTC_GUARDED_BY(&encoder_queue_);
317   absl::optional<uint32_t> encoder_target_bitrate_bps_
318       RTC_GUARDED_BY(&encoder_queue_);
319   size_t max_data_payload_length_ RTC_GUARDED_BY(&encoder_queue_);
320   absl::optional<EncoderRateSettings> last_encoder_rate_settings_
321       RTC_GUARDED_BY(&encoder_queue_);
322   bool encoder_paused_and_dropped_frame_ RTC_GUARDED_BY(&encoder_queue_);
323 
324   // Set to true if at least one frame was sent to encoder since last encoder
325   // initialization.
326   bool was_encode_called_since_last_initialization_
327       RTC_GUARDED_BY(&encoder_queue_);
328 
329   bool encoder_failed_ RTC_GUARDED_BY(&encoder_queue_);
330   Clock* const clock_;
331 
332   // Used to make sure incoming time stamp is increasing for every frame.
333   int64_t last_captured_timestamp_ RTC_GUARDED_BY(&encoder_queue_);
334   // Delta used for translating between NTP and internal timestamps.
335   const int64_t delta_ntp_internal_ms_ RTC_GUARDED_BY(&encoder_queue_);
336 
337   int64_t last_frame_log_ms_ RTC_GUARDED_BY(&encoder_queue_);
338   int captured_frame_count_ RTC_GUARDED_BY(&encoder_queue_);
339   int dropped_frame_cwnd_pushback_count_ RTC_GUARDED_BY(&encoder_queue_);
340   int dropped_frame_encoder_block_count_ RTC_GUARDED_BY(&encoder_queue_);
341   absl::optional<VideoFrame> pending_frame_ RTC_GUARDED_BY(&encoder_queue_);
342   int64_t pending_frame_post_time_us_ RTC_GUARDED_BY(&encoder_queue_);
343 
344   VideoFrame::UpdateRect accumulated_update_rect_
345       RTC_GUARDED_BY(&encoder_queue_);
346   bool accumulated_update_rect_is_valid_ RTC_GUARDED_BY(&encoder_queue_);
347 
348   // Used for automatic content type detection.
349   absl::optional<VideoFrame::UpdateRect> last_update_rect_
350       RTC_GUARDED_BY(&encoder_queue_);
351   Timestamp animation_start_time_ RTC_GUARDED_BY(&encoder_queue_);
352   bool cap_resolution_due_to_video_content_ RTC_GUARDED_BY(&encoder_queue_);
353   // Used to correctly ignore changes in update_rect introduced by
354   // resize triggered by animation detection.
355   enum class ExpectResizeState {
356     kNoResize,              // Normal operation.
357     kResize,                // Resize was triggered by the animation detection.
358     kFirstFrameAfterResize  // Resize observed.
359   } expect_resize_state_ RTC_GUARDED_BY(&encoder_queue_);
360 
361   FecControllerOverride* fec_controller_override_
362       RTC_GUARDED_BY(&encoder_queue_);
363   absl::optional<int64_t> last_parameters_update_ms_
364       RTC_GUARDED_BY(&encoder_queue_);
365   absl::optional<int64_t> last_encode_info_ms_ RTC_GUARDED_BY(&encoder_queue_);
366 
367   VideoEncoder::EncoderInfo encoder_info_ RTC_GUARDED_BY(&encoder_queue_);
368   VideoCodec send_codec_ RTC_GUARDED_BY(&encoder_queue_);
369 
370   FrameDropper frame_dropper_ RTC_GUARDED_BY(&encoder_queue_);
371   // If frame dropper is not force disabled, frame dropping might still be
372   // disabled if VideoEncoder::GetEncoderInfo() indicates that the encoder has a
373   // trusted rate controller. This is determined on a per-frame basis, as the
374   // encoder behavior might dynamically change.
375   bool force_disable_frame_dropper_ RTC_GUARDED_BY(&encoder_queue_);
376   // Incremented on worker thread whenever `frame_dropper_` determines that a
377   // frame should be dropped. Decremented on whichever thread runs
378   // OnEncodedImage(), which is only called by one thread but not necessarily
379   // the worker thread.
380   std::atomic<int> pending_frame_drops_;
381 
382   // Congestion window frame drop ratio (drop 1 in every
383   // cwnd_frame_drop_interval_ frames).
384   absl::optional<int> cwnd_frame_drop_interval_ RTC_GUARDED_BY(&encoder_queue_);
385   // Frame counter for congestion window frame drop.
386   int cwnd_frame_counter_ RTC_GUARDED_BY(&encoder_queue_);
387 
388   std::unique_ptr<EncoderBitrateAdjuster> bitrate_adjuster_
389       RTC_GUARDED_BY(&encoder_queue_);
390 
391   // TODO(sprang): Change actually support keyframe per simulcast stream, or
392   // turn this into a simple bool `pending_keyframe_request_`.
393   std::vector<VideoFrameType> next_frame_types_ RTC_GUARDED_BY(&encoder_queue_);
394 
395   FrameEncodeMetadataWriter frame_encode_metadata_writer_;
396 
397   // Experiment groups parsed from field trials for realtime video ([0]) and
398   // screenshare ([1]). 0 means no group specified. Positive values are
399   // experiment group numbers incremented by 1.
400   const std::array<uint8_t, 2> experiment_groups_;
401 
402   struct AutomaticAnimationDetectionExperiment {
403     bool enabled = false;
404     int min_duration_ms = 2000;
405     double min_area_ratio = 0.8;
406     int min_fps = 10;
ParserAutomaticAnimationDetectionExperiment407     std::unique_ptr<StructParametersParser> Parser() {
408       return StructParametersParser::Create(
409           "enabled", &enabled,                  //
410           "min_duration_ms", &min_duration_ms,  //
411           "min_area_ratio", &min_area_ratio,    //
412           "min_fps", &min_fps);
413     }
414   };
415 
416   AutomaticAnimationDetectionExperiment
417   ParseAutomatincAnimationDetectionFieldTrial() const;
418 
419   AutomaticAnimationDetectionExperiment
420       automatic_animation_detection_experiment_ RTC_GUARDED_BY(&encoder_queue_);
421 
422   // Provides video stream input states: current resolution and frame rate.
423   VideoStreamInputStateProvider input_state_provider_;
424 
425   const std::unique_ptr<VideoStreamAdapter> video_stream_adapter_
426       RTC_GUARDED_BY(&encoder_queue_);
427   // Responsible for adapting input resolution or frame rate to ensure resources
428   // (e.g. CPU or bandwidth) are not overused. Adding resources can occur on any
429   // thread.
430   std::unique_ptr<ResourceAdaptationProcessorInterface>
431       resource_adaptation_processor_ RTC_GUARDED_BY(&encoder_queue_);
432   std::unique_ptr<DegradationPreferenceManager> degradation_preference_manager_
433       RTC_GUARDED_BY(&encoder_queue_);
434   std::vector<AdaptationConstraint*> adaptation_constraints_
435       RTC_GUARDED_BY(&encoder_queue_);
436   // Handles input, output and stats reporting related to VideoStreamEncoder
437   // specific resources, such as "encode usage percent" measurements and "QP
438   // scaling". Also involved with various mitigations such as initial frame
439   // dropping.
440   // The manager primarily operates on the `encoder_queue_` but its lifetime is
441   // tied to the VideoStreamEncoder (which is destroyed off the encoder queue)
442   // and its resource list is accessible from any thread.
443   VideoStreamEncoderResourceManager stream_resource_manager_
444       RTC_GUARDED_BY(&encoder_queue_);
445   std::vector<rtc::scoped_refptr<Resource>> additional_resources_
446       RTC_GUARDED_BY(&encoder_queue_);
447   // Carries out the VideoSourceRestrictions provided by the
448   // ResourceAdaptationProcessor, i.e. reconfigures the source of video frames
449   // to provide us with different resolution or frame rate.
450   // This class is thread-safe.
451   VideoSourceSinkController video_source_sink_controller_
452       RTC_GUARDED_BY(worker_queue_);
453 
454   // Default bitrate limits in EncoderInfoSettings allowed.
455   const bool default_limits_allowed_;
456 
457   // QP parser is used to extract QP value from encoded frame when that is not
458   // provided by encoder.
459   QpParser qp_parser_;
460   const bool qp_parsing_allowed_;
461 
462   // Enables encoder switching on initialization failures.
463   bool switch_encoder_on_init_failures_;
464 
465   const absl::optional<int> vp9_low_tier_core_threshold_;
466 
467   // These are copies of restrictions (glorified max_pixel_count) set by
468   // a) OnVideoSourceRestrictionsUpdated
469   // b) CheckForAnimatedContent
470   // They are used to scale down encoding resolution if needed when using
471   // requested_resolution.
472   //
473   // TODO(webrtc:14451) Split video_source_sink_controller_
474   // so that ownership on restrictions/wants is kept on &encoder_queue_, that
475   // these extra copies would not be needed.
476   absl::optional<VideoSourceRestrictions> latest_restrictions_
477       RTC_GUARDED_BY(&encoder_queue_);
478   absl::optional<VideoSourceRestrictions> animate_restrictions_
479       RTC_GUARDED_BY(&encoder_queue_);
480 
481   // Used to cancel any potentially pending tasks to the worker thread.
482   // Refrenced by tasks running on `encoder_queue_` so need to be destroyed
483   // after stopping that queue. Must be created and destroyed on
484   // `worker_queue_`.
485   ScopedTaskSafety task_safety_;
486 
487   // Public methods are proxied to the task queues. The queues must be destroyed
488   // first to make sure no tasks run that use other members.
489   rtc::TaskQueue encoder_queue_;
490 };
491 
492 }  // namespace webrtc
493 
494 #endif  // VIDEO_VIDEO_STREAM_ENCODER_H_
495