blob: f4c3e6f53e854614b609f1bf2b46bf16d1db9ea1 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
stefan@webrtc.org07b45a52012-02-02 08:37:48 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
Peter Boström7623ce42015-12-09 12:13:30 +010011#ifndef WEBRTC_VIDEO_VIE_ENCODER_H_
12#define WEBRTC_VIDEO_VIE_ENCODER_H_
niklase@google.com470e71d2011-07-07 08:21:25 +000013
kwiberg27f982b2016-03-01 11:52:33 -080014#include <memory>
perkj376b1922016-05-02 11:35:24 -070015#include <string>
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000016#include <vector>
mflodman@webrtc.orgd6ec3862012-10-25 11:30:29 +000017
nisseaf916892017-01-10 07:44:26 -080018#include "webrtc/api/video/video_rotation.h"
Tommi97888bd2016-01-21 23:24:59 +010019#include "webrtc/base/criticalsection.h"
perkj26091b12016-09-01 01:17:40 -070020#include "webrtc/base/event.h"
21#include "webrtc/base/sequenced_task_checker.h"
22#include "webrtc/base/task_queue.h"
ossuf515ab82016-12-07 04:52:58 -080023#include "webrtc/call/call.h"
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000024#include "webrtc/common_types.h"
Erik Språng08127a92016-11-16 16:41:30 +010025#include "webrtc/common_video/include/video_bitrate_allocator.h"
nissed30a1112016-04-18 05:15:22 -070026#include "webrtc/media/base/videosinkinterface.h"
Henrik Kjellander2557b862015-11-18 22:00:21 +010027#include "webrtc/modules/video_coding/include/video_coding_defines.h"
kthelgason876222f2016-11-29 01:44:11 -080028#include "webrtc/modules/video_coding/utility/quality_scaler.h"
Peter Boströmcd5c25c2016-04-21 16:48:08 +020029#include "webrtc/modules/video_coding/video_coding_impl.h"
perkj26091b12016-09-01 01:17:40 -070030#include "webrtc/system_wrappers/include/atomic32.h"
ossuf515ab82016-12-07 04:52:58 -080031#include "webrtc/typedefs.h"
perkj26091b12016-09-01 01:17:40 -070032#include "webrtc/video/overuse_frame_detector.h"
33#include "webrtc/video_encoder.h"
34#include "webrtc/video_send_stream.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000035
36namespace webrtc {
mflodman@webrtc.org84d17832011-12-01 17:02:23 +000037
niklase@google.com470e71d2011-07-07 08:21:25 +000038class ProcessThread;
pbos@webrtc.org273a4142014-12-01 15:23:21 +000039class SendStatisticsProxy;
sprang1a646ee2016-12-01 06:34:11 -080040class VideoBitrateAllocationObserver;
niklase@google.com470e71d2011-07-07 08:21:25 +000041
perkjbc75d972016-05-02 06:31:25 -070042// VieEncoder represent a video encoder that accepts raw video frames as input
43// and produces an encoded bit stream.
44// Usage:
perkj26091b12016-09-01 01:17:40 -070045// Instantiate.
perkja49cbd32016-09-16 07:53:41 -070046// Call SetSink.
47// Call SetSource.
perkj26091b12016-09-01 01:17:40 -070048// Call ConfigureEncoder with the codec settings.
perkj26091b12016-09-01 01:17:40 -070049// Call Stop() when done.
perkja49cbd32016-09-16 07:53:41 -070050class ViEEncoder : public rtc::VideoSinkInterface<VideoFrame>,
perkj26091b12016-09-01 01:17:40 -070051 public EncodedImageCallback,
52 public VCMSendStatisticsCallback,
sprangb1ca0732017-02-01 08:38:12 -080053 public AdaptationObserverInterface {
mflodman@webrtc.org84d17832011-12-01 17:02:23 +000054 public:
Per512ecb32016-09-23 15:52:06 +020055 // Interface for receiving encoded video frames and notifications about
56 // configuration changes.
57 class EncoderSink : public EncodedImageCallback {
58 public:
59 virtual void OnEncoderConfigurationChanged(
60 std::vector<VideoStream> streams,
61 int min_transmit_bitrate_bps) = 0;
62 };
63
kthelgason876222f2016-11-29 01:44:11 -080064 // Downscale resolution at most 2 times for CPU reasons.
perkj803d97f2016-11-01 11:45:46 -070065 static const int kMaxCpuDowngrades = 2;
66
mflodman0dbf0092015-10-19 08:12:12 -070067 ViEEncoder(uint32_t number_of_cores,
Peter Boström7083e112015-09-22 16:28:51 +020068 SendStatisticsProxy* stats_proxy,
perkj803d97f2016-11-01 11:45:46 -070069 const VideoSendStream::Config::EncoderSettings& settings,
perkj26091b12016-09-01 01:17:40 -070070 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback,
perkj26091b12016-09-01 01:17:40 -070071 EncodedFrameObserver* encoder_timing);
mflodman@webrtc.org84d17832011-12-01 17:02:23 +000072 ~ViEEncoder();
perkj26091b12016-09-01 01:17:40 -070073 // RegisterProcessThread register |module_process_thread| with those objects
74 // that use it. Registration has to happen on the thread where
75 // |module_process_thread| was created (libjingle's worker thread).
76 // TODO(perkj): Replace the use of |module_process_thread| with a TaskQueue.
77 void RegisterProcessThread(ProcessThread* module_process_thread);
78 void DeRegisterProcessThread();
niklase@google.com470e71d2011-07-07 08:21:25 +000079
perkj803d97f2016-11-01 11:45:46 -070080 // Sets the source that will provide I420 video frames.
81 // |degradation_preference| control whether or not resolution or frame rate
82 // may be reduced.
83 void SetSource(
84 rtc::VideoSourceInterface<VideoFrame>* source,
85 const VideoSendStream::DegradationPreference& degradation_preference);
86
87 // Sets the |sink| that gets the encoded frames. |rotation_applied| means
88 // that the source must support rotation. Only set |rotation_applied| if the
89 // remote side does not support the rotation extension.
90 void SetSink(EncoderSink* sink, bool rotation_applied);
mflodman@webrtc.org02270cd2015-02-06 13:10:19 +000091
perkj26091b12016-09-01 01:17:40 -070092 // TODO(perkj): Can we remove VideoCodec.startBitrate ?
93 void SetStartBitrate(int start_bitrate_bps);
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +000094
sprang1a646ee2016-12-01 06:34:11 -080095 void SetBitrateObserver(VideoBitrateAllocationObserver* bitrate_observer);
96
Per512ecb32016-09-23 15:52:06 +020097 void ConfigureEncoder(VideoEncoderConfig config,
asapersson5f7226f2016-11-25 04:37:00 -080098 size_t max_data_payload_length,
99 bool nack_enabled);
niklase@google.com470e71d2011-07-07 08:21:25 +0000100
perkj26091b12016-09-01 01:17:40 -0700101 // Permanently stop encoding. After this method has returned, it is
102 // guaranteed that no encoded frames will be delivered to the sink.
103 void Stop();
104
Peter Boström233bfd22016-01-18 20:23:40 +0100105 void SendKeyFrame();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +0000106
Peter Boström0013dcc2016-02-19 20:42:19 +0100107 // virtual to test EncoderStateFeedback with mocks.
perkj600246e2016-05-04 11:26:51 -0700108 virtual void OnReceivedIntraFrameRequest(size_t stream_index);
109 virtual void OnReceivedSLI(uint8_t picture_id);
110 virtual void OnReceivedRPSI(uint64_t picture_id);
mflodman@webrtc.orgd6ec3862012-10-25 11:30:29 +0000111
mflodman86aabb22016-03-11 15:44:32 +0100112 void OnBitrateUpdated(uint32_t bitrate_bps,
stefan@webrtc.orgedeea912014-12-08 19:46:23 +0000113 uint8_t fraction_lost,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000114 int64_t round_trip_time_ms);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +0000115
perkj803d97f2016-11-01 11:45:46 -0700116 protected:
kthelgason876222f2016-11-29 01:44:11 -0800117 // Used for testing. For example the |ScalingObserverInterface| methods must
118 // be called on |encoder_queue_|.
perkj803d97f2016-11-01 11:45:46 -0700119 rtc::TaskQueue* encoder_queue() { return &encoder_queue_; }
120
kthelgason876222f2016-11-29 01:44:11 -0800121 // webrtc::ScalingObserverInterface implementation.
perkj803d97f2016-11-01 11:45:46 -0700122 // These methods are protected for easier testing.
sprangb1ca0732017-02-01 08:38:12 -0800123 void AdaptUp(AdaptReason reason) override;
124 void AdaptDown(AdaptReason reason) override;
perkj803d97f2016-11-01 11:45:46 -0700125
mflodman@webrtc.org84d17832011-12-01 17:02:23 +0000126 private:
Pera48ddb72016-09-29 11:48:50 +0200127 class ConfigureEncoderTask;
perkj26091b12016-09-01 01:17:40 -0700128 class EncodeTask;
perkja49cbd32016-09-16 07:53:41 -0700129 class VideoSourceProxy;
perkj26091b12016-09-01 01:17:40 -0700130
kthelgason93f16d72017-01-16 06:15:23 -0800131 class VideoFrameInfo {
132 public:
perkjfa10b552016-10-02 23:45:26 -0700133 VideoFrameInfo(int width,
134 int height,
135 VideoRotation rotation,
136 bool is_texture)
137 : width(width),
138 height(height),
139 rotation(rotation),
140 is_texture(is_texture) {}
141 int width;
142 int height;
Per21d45d22016-10-30 21:37:57 +0100143 VideoRotation rotation;
perkjfa10b552016-10-02 23:45:26 -0700144 bool is_texture;
kthelgason93f16d72017-01-16 06:15:23 -0800145 int pixel_count() const { return width * height; }
perkjfa10b552016-10-02 23:45:26 -0700146 };
147
Pera48ddb72016-09-29 11:48:50 +0200148 void ConfigureEncoderOnTaskQueue(VideoEncoderConfig config,
asapersson5f7226f2016-11-25 04:37:00 -0800149 size_t max_data_payload_length,
150 bool nack_enabled);
perkjfa10b552016-10-02 23:45:26 -0700151 void ReconfigureEncoder();
perkj26091b12016-09-01 01:17:40 -0700152
kthelgason2bc68642017-02-07 07:02:22 -0800153 void ConfigureQualityScaler();
154
perkja49cbd32016-09-16 07:53:41 -0700155 // Implements VideoSinkInterface.
156 void OnFrame(const VideoFrame& video_frame) override;
157
perkj26091b12016-09-01 01:17:40 -0700158 // Implements VideoSendStatisticsCallback.
159 void SendStatistics(uint32_t bit_rate,
160 uint32_t frame_rate) override;
161
perkjd52063f2016-09-07 06:32:18 -0700162 void EncodeVideoFrame(const VideoFrame& frame,
163 int64_t time_when_posted_in_ms);
perkj26091b12016-09-01 01:17:40 -0700164
165 // Implements EncodedImageCallback.
166 EncodedImageCallback::Result OnEncodedImage(
167 const EncodedImage& encoded_image,
168 const CodecSpecificInfo* codec_specific_info,
169 const RTPFragmentationHeader* fragmentation) override;
170
kthelgason876222f2016-11-29 01:44:11 -0800171 void OnDroppedFrame() override;
172
perkj26091b12016-09-01 01:17:40 -0700173 bool EncoderPaused() const;
174 void TraceFrameDropStart();
175 void TraceFrameDropEnd();
176
177 rtc::Event shutdown_event_;
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000178
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000179 const uint32_t number_of_cores_;
kthelgason2bc68642017-02-07 07:02:22 -0800180 // Counts how many frames we've dropped in the initial rampup phase.
181 int initial_rampup_;
perkja49cbd32016-09-16 07:53:41 -0700182
183 const std::unique_ptr<VideoSourceProxy> source_proxy_;
Per512ecb32016-09-23 15:52:06 +0200184 EncoderSink* sink_;
perkj26091b12016-09-01 01:17:40 -0700185 const VideoSendStream::Config::EncoderSettings settings_;
Pera48ddb72016-09-29 11:48:50 +0200186 const VideoCodecType codec_type_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000187
perkj26091b12016-09-01 01:17:40 -0700188 vcm::VideoSender video_sender_ ACCESS_ON(&encoder_queue_);
perkjd52063f2016-09-07 06:32:18 -0700189 OveruseFrameDetector overuse_detector_ ACCESS_ON(&encoder_queue_);
kthelgason876222f2016-11-29 01:44:11 -0800190 std::unique_ptr<QualityScaler> quality_scaler_ ACCESS_ON(&encoder_queue_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +0000191
Peter Boström7083e112015-09-22 16:28:51 +0200192 SendStatisticsProxy* const stats_proxy_;
perkj26091b12016-09-01 01:17:40 -0700193 rtc::VideoSinkInterface<VideoFrame>* const pre_encode_callback_;
Peter Boström7083e112015-09-22 16:28:51 +0200194 ProcessThread* module_process_thread_;
perkj26091b12016-09-01 01:17:40 -0700195 rtc::ThreadChecker module_process_thread_checker_;
perkja49cbd32016-09-16 07:53:41 -0700196 // |thread_checker_| checks that public methods that are related to lifetime
197 // of ViEEncoder are called on the same thread.
198 rtc::ThreadChecker thread_checker_;
mflodman@webrtc.org84d17832011-12-01 17:02:23 +0000199
Pera48ddb72016-09-29 11:48:50 +0200200 VideoEncoderConfig encoder_config_ ACCESS_ON(&encoder_queue_);
Erik Språng08127a92016-11-16 16:41:30 +0100201 std::unique_ptr<VideoBitrateAllocator> rate_allocator_
Pera48ddb72016-09-29 11:48:50 +0200202 ACCESS_ON(&encoder_queue_);
mflodman@webrtc.org84d17832011-12-01 17:02:23 +0000203
perkjfa10b552016-10-02 23:45:26 -0700204 // Set when ConfigureEncoder has been called in order to lazy reconfigure the
205 // encoder on the next frame.
206 bool pending_encoder_reconfiguration_ ACCESS_ON(&encoder_queue_);
207 rtc::Optional<VideoFrameInfo> last_frame_info_ ACCESS_ON(&encoder_queue_);
Pera48ddb72016-09-29 11:48:50 +0200208 uint32_t encoder_start_bitrate_bps_ ACCESS_ON(&encoder_queue_);
209 size_t max_data_payload_length_ ACCESS_ON(&encoder_queue_);
asapersson5f7226f2016-11-25 04:37:00 -0800210 bool nack_enabled_ ACCESS_ON(&encoder_queue_);
perkj26091b12016-09-01 01:17:40 -0700211 uint32_t last_observed_bitrate_bps_ ACCESS_ON(&encoder_queue_);
212 bool encoder_paused_and_dropped_frame_ ACCESS_ON(&encoder_queue_);
213 bool has_received_sli_ ACCESS_ON(&encoder_queue_);
214 uint8_t picture_id_sli_ ACCESS_ON(&encoder_queue_);
215 bool has_received_rpsi_ ACCESS_ON(&encoder_queue_);
216 uint64_t picture_id_rpsi_ ACCESS_ON(&encoder_queue_);
217 Clock* const clock_;
kthelgason876222f2016-11-29 01:44:11 -0800218 // Counters used for deciding if the video resolution is currently
219 // restricted, and if so, why.
kthelgason0cd27ba2016-12-19 06:32:16 -0800220 std::vector<int> scale_counter_ ACCESS_ON(&encoder_queue_);
kthelgason876222f2016-11-29 01:44:11 -0800221 // Set depending on degradation preferences
sprangb1ca0732017-02-01 08:38:12 -0800222 VideoSendStream::DegradationPreference degradation_preference_
223 ACCESS_ON(&encoder_queue_);
perkj803d97f2016-11-01 11:45:46 -0700224
perkj803d97f2016-11-01 11:45:46 -0700225 // Pixel count last time the resolution was requested to be changed down.
226 rtc::Optional<int> max_pixel_count_ ACCESS_ON(&encoder_queue_);
227 // Pixel count last time the resolution was requested to be changed up.
228 rtc::Optional<int> max_pixel_count_step_up_ ACCESS_ON(&encoder_queue_);
229
230 rtc::RaceChecker incoming_frame_race_checker_
231 GUARDED_BY(incoming_frame_race_checker_);
perkj26091b12016-09-01 01:17:40 -0700232 Atomic32 posted_frames_waiting_for_encode_;
233 // Used to make sure incoming time stamp is increasing for every frame.
234 int64_t last_captured_timestamp_ GUARDED_BY(incoming_frame_race_checker_);
235 // Delta used for translating between NTP and internal timestamps.
perkj803d97f2016-11-01 11:45:46 -0700236 const int64_t delta_ntp_internal_ms_ GUARDED_BY(incoming_frame_race_checker_);
perkj26091b12016-09-01 01:17:40 -0700237
asapersson6ffb67d2016-09-12 00:10:45 -0700238 int64_t last_frame_log_ms_ GUARDED_BY(incoming_frame_race_checker_);
239 int captured_frame_count_ ACCESS_ON(&encoder_queue_);
240 int dropped_frame_count_ ACCESS_ON(&encoder_queue_);
241
sprang1a646ee2016-12-01 06:34:11 -0800242 VideoBitrateAllocationObserver* bitrate_observer_ ACCESS_ON(&encoder_queue_);
sprang57c2fff2017-01-16 06:24:02 -0800243 rtc::Optional<int64_t> last_parameters_update_ms_ ACCESS_ON(&encoder_queue_);
sprang1a646ee2016-12-01 06:34:11 -0800244
perkj26091b12016-09-01 01:17:40 -0700245 // All public methods are proxied to |encoder_queue_|. It must must be
246 // destroyed first to make sure no tasks are run that use other members.
247 rtc::TaskQueue encoder_queue_;
perkja49cbd32016-09-16 07:53:41 -0700248
249 RTC_DISALLOW_COPY_AND_ASSIGN(ViEEncoder);
niklase@google.com470e71d2011-07-07 08:21:25 +0000250};
mflodman@webrtc.org84d17832011-12-01 17:02:23 +0000251
252} // namespace webrtc
253
Peter Boström7623ce42015-12-09 12:13:30 +0100254#endif // WEBRTC_VIDEO_VIE_ENCODER_H_