Index: webrtc/video_encoder.h |
diff --git a/webrtc/video_encoder.h b/webrtc/video_encoder.h |
index 9e7e4d7040f2fd8401ac934144619612f5fe750a..5e94c87da8dc4cac976d40133243f684d884e792 100644 |
--- a/webrtc/video_encoder.h |
+++ b/webrtc/video_encoder.h |
@@ -14,6 +14,7 @@ |
#include <string> |
#include <vector> |
+#include "webrtc/base/rollingaccumulator.h" |
#include "webrtc/common_types.h" |
#include "webrtc/typedefs.h" |
#include "webrtc/video_frame.h" |
@@ -125,6 +126,7 @@ class VideoEncoder { |
virtual void OnDroppedFrame() {} |
virtual int GetTargetFramerate() { return -1; } |
virtual bool SupportsNativeHandle() const { return false; } |
+ virtual bool IsHardwareEncoder() const { return false; } |
virtual const char* ImplementationName() const { return "unknown"; } |
}; |
@@ -181,5 +183,70 @@ class VideoEncoderSoftwareFallbackWrapper : public VideoEncoder { |
std::string fallback_implementation_name_; |
EncodedImageCallback* callback_; |
}; |
+ |
+// Class used to wrap hardware encoders that don't properly respect their set |
+// bitrates. This class will observe input vs output bitrate, and dynamically |
+// adjust the bitrate setting on the wrapped encoder so that its output matches |
+// the rate we need. |
+class HardwareVideoEncoderWrapper : public VideoEncoder { |
+ public: |
+ HardwareVideoEncoderWrapper(webrtc::VideoEncoder* encoder); |
+ virtual ~HardwareVideoEncoderWrapper() {} |
+ |
+ int32_t InitEncode(const VideoCodec* codec_settings, |
+ int32_t number_of_cores, |
+ size_t max_payload_size) override; |
+ |
+ int32_t RegisterEncodeCompleteCallback( |
+ EncodedImageCallback* callback) override; |
+ |
+ int32_t Release() override; |
+ int32_t Encode(const VideoFrame& frame, |
+ const CodecSpecificInfo* codec_specific_info, |
+ const std::vector<FrameType>* frame_types) override; |
+ int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) override; |
+ |
+ int32_t SetRates(uint32_t bitrate, uint32_t framerate) override; |
+ void OnDroppedFrame() override; |
+ int GetTargetFramerate() override; |
+ bool SupportsNativeHandle() const override; |
+ bool IsHardwareEncoder() const override; |
+ const char* ImplementationName() const override; |
+ |
+ // Called when wrapped encoder reports an encoded frame. |
+ int32_t OnFrameEncoded(const EncodedImage& encoded_image, |
+ const CodecSpecificInfo* codec_specific_info, |
+ const RTPFragmentationHeader* fragmentation); |
+ |
+ private: |
+ static const uint32_t kBitrateUpdateIntervalMs = 2000; // 2s. |
+ static const uint32_t kBitrateTolerancePct = 5; // 5 percent of original. |
+ |
+ // Updates the bitrate set on the wrapped encoder with relevant penalties. |
+ void UpdateBitrate(uint32_t current_time_ms); |
+ // Updates the bitrate tracker with a new sample. |
+ void UpdateBitrateTracker(size_t frame_size, uint32_t current_time_ms); |
+ |
+ // Wrapped encoder. |
+ webrtc::VideoEncoder* const encoder_; |
+ // The callback registered with this wrapper. |
+ EncodedImageCallback* callback_; |
+ // The callback registered with wrapped encoder. |
+ rtc::scoped_ptr<EncodedImageCallback> wrapped_callback_; |
+ // Simple moving average bitrate estimator. |
+ rtc::RollingAccumulator<float> bitrate_tracker_; |
+ |
+ // The bitrate set in SetRates. |
+ uint32_t original_bitrate_; |
+ // The framerate set in SetRates. |
+ uint32_t original_frame_rate_; |
+ // The bitrate used to call SetRates on the wrapped encoder. |
+ uint32_t adjusted_bitrate_; |
+ // The last time we update the bitrate. |
+ uint32_t last_bitrate_update_time_ms_; |
+ // The timestamp of the last frame received from the wrapped encoder. |
+ uint32_t last_frame_time_ms_; |
+}; |
+ |
} // namespace webrtc |
#endif // WEBRTC_VIDEO_ENCODER_H_ |