From 6aca0b743e58b7d4e95cc28b2c296c98d4281f48 Mon Sep 17 00:00:00 2001 From: Ilya Nikolaevskiy Date: Wed, 13 Feb 2019 11:55:57 +0100 Subject: [PATCH] Add |update_rect| field and UpdateRect struct to VideoFrame. Bug: webrtc:10310 Change-Id: I6d60d8a3bf5a9c15fb8d4cb4e8adf08642f27802 Reviewed-on: https://webrtc-review.googlesource.com/c/122564 Commit-Queue: Ilya Nikolaevskiy Reviewed-by: Niels Moller Cr-Commit-Position: refs/heads/master@{#26660} --- api/video/video_frame.cc | 27 ++++++++++++++---- api/video/video_frame.h | 28 ++++++++++++++++++- ...oder_software_fallback_wrapper_unittest.cc | 12 ++++++-- 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/api/video/video_frame.cc b/api/video/video_frame.cc index 6a9e3f7869..e91eedede8 100644 --- a/api/video/video_frame.cc +++ b/api/video/video_frame.cc @@ -20,8 +20,9 @@ VideoFrame::Builder::Builder() = default; VideoFrame::Builder::~Builder() = default; VideoFrame VideoFrame::Builder::build() { + RTC_CHECK(video_frame_buffer_ != nullptr); return VideoFrame(id_, video_frame_buffer_, timestamp_us_, timestamp_rtp_, - ntp_time_ms_, rotation_, color_space_); + ntp_time_ms_, rotation_, color_space_, update_rect_); } VideoFrame::Builder& VideoFrame::Builder::set_video_frame_buffer( @@ -76,6 +77,12 @@ VideoFrame::Builder& VideoFrame::Builder::set_id(uint16_t id) { return *this; } +VideoFrame::Builder& VideoFrame::Builder::set_update_rect( + const VideoFrame::UpdateRect& update_rect) { + update_rect_ = update_rect; + return *this; +} + VideoFrame::VideoFrame(const rtc::scoped_refptr& buffer, webrtc::VideoRotation rotation, int64_t timestamp_us) @@ -83,7 +90,8 @@ VideoFrame::VideoFrame(const rtc::scoped_refptr& buffer, timestamp_rtp_(0), ntp_time_ms_(0), timestamp_us_(timestamp_us), - rotation_(rotation) {} + rotation_(rotation), + update_rect_{0, 0, buffer->width(), buffer->height()} {} VideoFrame::VideoFrame(const rtc::scoped_refptr& buffer, uint32_t timestamp_rtp, @@ -93,7 +101,8 @@ VideoFrame::VideoFrame(const rtc::scoped_refptr& buffer, timestamp_rtp_(timestamp_rtp), ntp_time_ms_(0), timestamp_us_(render_time_ms * rtc::kNumMicrosecsPerMillisec), - rotation_(rotation) { + rotation_(rotation), + update_rect_{0, 0, buffer->width(), buffer->height()} { RTC_DCHECK(buffer); } @@ -103,14 +112,22 @@ VideoFrame::VideoFrame(uint16_t id, uint32_t timestamp_rtp, int64_t ntp_time_ms, VideoRotation rotation, - const absl::optional& color_space) + const absl::optional& color_space, + const absl::optional& update_rect) : id_(id), video_frame_buffer_(buffer), timestamp_rtp_(timestamp_rtp), ntp_time_ms_(ntp_time_ms), timestamp_us_(timestamp_us), rotation_(rotation), - color_space_(color_space) {} + color_space_(color_space), + update_rect_(update_rect.value_or(UpdateRect{ + 0, 0, video_frame_buffer_->width(), video_frame_buffer_->height()})) { + RTC_DCHECK_GE(update_rect_.offset_x, 0); + RTC_DCHECK_GE(update_rect_.offset_y, 0); + RTC_DCHECK_LE(update_rect_.offset_x + update_rect_.width, width()); + RTC_DCHECK_LE(update_rect_.offset_y + update_rect_.height, height()); +} VideoFrame::~VideoFrame() = default; diff --git a/api/video/video_frame.h b/api/video/video_frame.h index e03057bf95..126c3d05de 100644 --- a/api/video/video_frame.h +++ b/api/video/video_frame.h @@ -19,12 +19,20 @@ #include "api/video/hdr_metadata.h" #include "api/video/video_frame_buffer.h" #include "api/video/video_rotation.h" +#include "rtc_base/checks.h" #include "rtc_base/system/rtc_export.h" namespace webrtc { class RTC_EXPORT VideoFrame { public: + struct UpdateRect { + int offset_x; + int offset_y; + int width; + int height; + }; + // Preferred way of building VideoFrame objects. class Builder { public: @@ -42,6 +50,7 @@ class RTC_EXPORT VideoFrame { Builder& set_color_space(const absl::optional& color_space); Builder& set_color_space(const ColorSpace* color_space); Builder& set_id(uint16_t id); + Builder& set_update_rect(const UpdateRect& update_rect); private: uint16_t id_ = 0; @@ -51,6 +60,7 @@ class RTC_EXPORT VideoFrame { int64_t ntp_time_ms_ = 0; VideoRotation rotation_ = kVideoRotation_0; absl::optional color_space_; + absl::optional update_rect_; }; // To be deprecated. Migrate all use to Builder. @@ -145,6 +155,18 @@ class RTC_EXPORT VideoFrame { return video_frame_buffer()->type() == VideoFrameBuffer::Type::kNative; } + // Always initialized to whole frame update, can be set by Builder or manually + // by |set_update_rect|. + UpdateRect update_rect() const { return update_rect_; } + // Rectangle must be within the frame dimensions. + void set_update_rect(const VideoFrame::UpdateRect& update_rect) { + RTC_DCHECK_GE(update_rect.offset_x, 0); + RTC_DCHECK_GE(update_rect.offset_y, 0); + RTC_DCHECK_LE(update_rect.offset_x + update_rect.width, width()); + RTC_DCHECK_LE(update_rect.offset_y + update_rect.height, height()); + update_rect_ = update_rect; + } + private: VideoFrame(uint16_t id, const rtc::scoped_refptr& buffer, @@ -152,7 +174,8 @@ class RTC_EXPORT VideoFrame { uint32_t timestamp_rtp, int64_t ntp_time_ms, VideoRotation rotation, - const absl::optional& color_space); + const absl::optional& color_space, + const absl::optional& update_rect); uint16_t id_; // An opaque reference counted handle that stores the pixel data. @@ -162,6 +185,9 @@ class RTC_EXPORT VideoFrame { int64_t timestamp_us_; VideoRotation rotation_; absl::optional color_space_; + // Updated since the last frame area. Unless set explicitly, will always be + // a full frame rectangle. + UpdateRect update_rect_; }; } // namespace webrtc diff --git a/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc b/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc index cdddbeb580..2822d693de 100644 --- a/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc +++ b/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc @@ -602,7 +602,9 @@ TEST(SoftwareFallbackEncoderTest, HwRateControllerTrusted) { // Trigger fallback to software. EXPECT_CALL(*hw_encoder, Encode) .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE)); - VideoFrame frame = VideoFrame::Builder().build(); + VideoFrame frame = VideoFrame::Builder() + .set_video_frame_buffer(I420Buffer::Create(100, 100)) + .build(); wrapper->Encode(frame, nullptr, nullptr); EXPECT_FALSE(wrapper->GetEncoderInfo().has_trusted_rate_controller); @@ -640,7 +642,9 @@ TEST(SoftwareFallbackEncoderTest, ReportsHardwareAccelerated) { // Trigger fallback to software. EXPECT_CALL(*hw_encoder, Encode) .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE)); - VideoFrame frame = VideoFrame::Builder().build(); + VideoFrame frame = VideoFrame::Builder() + .set_video_frame_buffer(I420Buffer::Create(100, 100)) + .build(); wrapper->Encode(frame, nullptr, nullptr); EXPECT_FALSE(wrapper->GetEncoderInfo().is_hardware_accelerated); } @@ -662,7 +666,9 @@ TEST(SoftwareFallbackEncoderTest, ReportsInternalSource) { // Trigger fallback to software. EXPECT_CALL(*hw_encoder, Encode) .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE)); - VideoFrame frame = VideoFrame::Builder().build(); + VideoFrame frame = VideoFrame::Builder() + .set_video_frame_buffer(I420Buffer::Create(100, 100)) + .build(); wrapper->Encode(frame, nullptr, nullptr); EXPECT_FALSE(wrapper->GetEncoderInfo().has_internal_source); }