blob: 0c564724d4b96e49d9bc9d3e9718a3d0d93efde1 [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
perkja49cbd32016-09-16 07:53:41 -0700153 // Implements VideoSinkInterface.
154 void OnFrame(const VideoFrame& video_frame) override;
155
perkj26091b12016-09-01 01:17:40 -0700156 // Implements VideoSendStatisticsCallback.
157 void SendStatistics(uint32_t bit_rate,
158 uint32_t frame_rate) override;
159
perkjd52063f2016-09-07 06:32:18 -0700160 void EncodeVideoFrame(const VideoFrame& frame,
161 int64_t time_when_posted_in_ms);
perkj26091b12016-09-01 01:17:40 -0700162
163 // Implements EncodedImageCallback.
164 EncodedImageCallback::Result OnEncodedImage(
165 const EncodedImage& encoded_image,
166 const CodecSpecificInfo* codec_specific_info,
167 const RTPFragmentationHeader* fragmentation) override;
168
kthelgason876222f2016-11-29 01:44:11 -0800169 void OnDroppedFrame() override;
170
perkj26091b12016-09-01 01:17:40 -0700171 bool EncoderPaused() const;
172 void TraceFrameDropStart();
173 void TraceFrameDropEnd();
174
175 rtc::Event shutdown_event_;
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000176
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000177 const uint32_t number_of_cores_;
perkja49cbd32016-09-16 07:53:41 -0700178
179 const std::unique_ptr<VideoSourceProxy> source_proxy_;
Per512ecb32016-09-23 15:52:06 +0200180 EncoderSink* sink_;
perkj26091b12016-09-01 01:17:40 -0700181 const VideoSendStream::Config::EncoderSettings settings_;
Pera48ddb72016-09-29 11:48:50 +0200182 const VideoCodecType codec_type_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000183
perkj26091b12016-09-01 01:17:40 -0700184 vcm::VideoSender video_sender_ ACCESS_ON(&encoder_queue_);
perkjd52063f2016-09-07 06:32:18 -0700185 OveruseFrameDetector overuse_detector_ ACCESS_ON(&encoder_queue_);
kthelgason876222f2016-11-29 01:44:11 -0800186 std::unique_ptr<QualityScaler> quality_scaler_ ACCESS_ON(&encoder_queue_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +0000187
Peter Boström7083e112015-09-22 16:28:51 +0200188 SendStatisticsProxy* const stats_proxy_;
perkj26091b12016-09-01 01:17:40 -0700189 rtc::VideoSinkInterface<VideoFrame>* const pre_encode_callback_;
Peter Boström7083e112015-09-22 16:28:51 +0200190 ProcessThread* module_process_thread_;
perkj26091b12016-09-01 01:17:40 -0700191 rtc::ThreadChecker module_process_thread_checker_;
perkja49cbd32016-09-16 07:53:41 -0700192 // |thread_checker_| checks that public methods that are related to lifetime
193 // of ViEEncoder are called on the same thread.
194 rtc::ThreadChecker thread_checker_;
mflodman@webrtc.org84d17832011-12-01 17:02:23 +0000195
Pera48ddb72016-09-29 11:48:50 +0200196 VideoEncoderConfig encoder_config_ ACCESS_ON(&encoder_queue_);
Erik Språng08127a92016-11-16 16:41:30 +0100197 std::unique_ptr<VideoBitrateAllocator> rate_allocator_
Pera48ddb72016-09-29 11:48:50 +0200198 ACCESS_ON(&encoder_queue_);
mflodman@webrtc.org84d17832011-12-01 17:02:23 +0000199
perkjfa10b552016-10-02 23:45:26 -0700200 // Set when ConfigureEncoder has been called in order to lazy reconfigure the
201 // encoder on the next frame.
202 bool pending_encoder_reconfiguration_ ACCESS_ON(&encoder_queue_);
203 rtc::Optional<VideoFrameInfo> last_frame_info_ ACCESS_ON(&encoder_queue_);
Pera48ddb72016-09-29 11:48:50 +0200204 uint32_t encoder_start_bitrate_bps_ ACCESS_ON(&encoder_queue_);
205 size_t max_data_payload_length_ ACCESS_ON(&encoder_queue_);
asapersson5f7226f2016-11-25 04:37:00 -0800206 bool nack_enabled_ ACCESS_ON(&encoder_queue_);
perkj26091b12016-09-01 01:17:40 -0700207 uint32_t last_observed_bitrate_bps_ ACCESS_ON(&encoder_queue_);
208 bool encoder_paused_and_dropped_frame_ ACCESS_ON(&encoder_queue_);
209 bool has_received_sli_ ACCESS_ON(&encoder_queue_);
210 uint8_t picture_id_sli_ ACCESS_ON(&encoder_queue_);
211 bool has_received_rpsi_ ACCESS_ON(&encoder_queue_);
212 uint64_t picture_id_rpsi_ ACCESS_ON(&encoder_queue_);
213 Clock* const clock_;
kthelgason876222f2016-11-29 01:44:11 -0800214 // Counters used for deciding if the video resolution is currently
215 // restricted, and if so, why.
kthelgason0cd27ba2016-12-19 06:32:16 -0800216 std::vector<int> scale_counter_ ACCESS_ON(&encoder_queue_);
kthelgason876222f2016-11-29 01:44:11 -0800217 // Set depending on degradation preferences
sprangb1ca0732017-02-01 08:38:12 -0800218 VideoSendStream::DegradationPreference degradation_preference_
219 ACCESS_ON(&encoder_queue_);
perkj803d97f2016-11-01 11:45:46 -0700220
perkj803d97f2016-11-01 11:45:46 -0700221 // Pixel count last time the resolution was requested to be changed down.
222 rtc::Optional<int> max_pixel_count_ ACCESS_ON(&encoder_queue_);
223 // Pixel count last time the resolution was requested to be changed up.
224 rtc::Optional<int> max_pixel_count_step_up_ ACCESS_ON(&encoder_queue_);
225
226 rtc::RaceChecker incoming_frame_race_checker_
227 GUARDED_BY(incoming_frame_race_checker_);
perkj26091b12016-09-01 01:17:40 -0700228 Atomic32 posted_frames_waiting_for_encode_;
229 // Used to make sure incoming time stamp is increasing for every frame.
230 int64_t last_captured_timestamp_ GUARDED_BY(incoming_frame_race_checker_);
231 // Delta used for translating between NTP and internal timestamps.
perkj803d97f2016-11-01 11:45:46 -0700232 const int64_t delta_ntp_internal_ms_ GUARDED_BY(incoming_frame_race_checker_);
perkj26091b12016-09-01 01:17:40 -0700233
asapersson6ffb67d2016-09-12 00:10:45 -0700234 int64_t last_frame_log_ms_ GUARDED_BY(incoming_frame_race_checker_);
235 int captured_frame_count_ ACCESS_ON(&encoder_queue_);
236 int dropped_frame_count_ ACCESS_ON(&encoder_queue_);
237
sprang1a646ee2016-12-01 06:34:11 -0800238 VideoBitrateAllocationObserver* bitrate_observer_ ACCESS_ON(&encoder_queue_);
sprang57c2fff2017-01-16 06:24:02 -0800239 rtc::Optional<int64_t> last_parameters_update_ms_ ACCESS_ON(&encoder_queue_);
sprang1a646ee2016-12-01 06:34:11 -0800240
perkj26091b12016-09-01 01:17:40 -0700241 // All public methods are proxied to |encoder_queue_|. It must must be
242 // destroyed first to make sure no tasks are run that use other members.
243 rtc::TaskQueue encoder_queue_;
perkja49cbd32016-09-16 07:53:41 -0700244
245 RTC_DISALLOW_COPY_AND_ASSIGN(ViEEncoder);
niklase@google.com470e71d2011-07-07 08:21:25 +0000246};
mflodman@webrtc.org84d17832011-12-01 17:02:23 +0000247
248} // namespace webrtc
249
Peter Boström7623ce42015-12-09 12:13:30 +0100250#endif // WEBRTC_VIDEO_VIE_ENCODER_H_