Index: remoting/codec/video_encoder_vpx.cc |
diff --git a/remoting/codec/video_encoder_vpx.cc b/remoting/codec/video_encoder_vpx.cc |
index adc6bf95a0508478cf05796a79490e3de2c524dd..3c5465232781014a36c3624587fab9c522c965d9 100644 |
--- a/remoting/codec/video_encoder_vpx.cc |
+++ b/remoting/codec/video_encoder_vpx.cc |
@@ -266,21 +266,9 @@ scoped_ptr<VideoPacket> VideoEncoderVpx::Encode( |
DCHECK_LE(32, frame.size().width()); |
DCHECK_LE(32, frame.size().height()); |
- if (!use_vp9_ || lossless_encode_) { |
- // Neither VP8 nor VP9-lossless support top-off, so ignore unchanged frames. |
- if (frame.updated_region().is_empty()) |
- return nullptr; |
- } else { |
- // Let VP9-lossy mode top-off, by continuing to pass it unchanged frames |
- // for a short while. |
- if (frame.updated_region().is_empty()) { |
- if (topoff_frame_count_ == 0) |
- return nullptr; |
- topoff_frame_count_--; |
- } else { |
- topoff_frame_count_ = 2; |
- } |
- } |
+ // If there is nothing to encode, and nothing to top-off, then return nothing. |
+ if (frame.updated_region().is_empty() && !encode_unchanged_frame_) |
+ return nullptr; |
base::TimeTicks encode_start_time = base::TimeTicks::Now(); |
@@ -300,8 +288,8 @@ scoped_ptr<VideoPacket> VideoEncoderVpx::Encode( |
// Apply active map to the encoder. |
vpx_active_map_t act_map; |
- act_map.rows = active_map_height_; |
- act_map.cols = active_map_width_; |
+ act_map.rows = active_map_size_.height(); |
+ act_map.cols = active_map_size_.width(); |
act_map.active_map = active_map_.get(); |
if (vpx_codec_control(codec_.get(), VP8E_SET_ACTIVEMAP, &act_map)) { |
LOG(ERROR) << "Unable to apply active map"; |
@@ -322,6 +310,9 @@ scoped_ptr<VideoPacket> VideoEncoderVpx::Encode( |
<< "Failed to fetch active map: " |
<< vpx_codec_err_to_string(ret) << "\n"; |
UpdateRegionFromActiveMap(&updated_region); |
+ |
+ // If the encoder output no changes then there's nothing left to top-off. |
+ encode_unchanged_frame_ = !updated_region.is_empty(); |
} |
// Read the encoded data. |
@@ -357,7 +348,8 @@ scoped_ptr<VideoPacket> VideoEncoderVpx::Encode( |
return packet.Pass(); |
} |
-VideoEncoderVpx::VideoEncoderVpx(bool use_vp9) : use_vp9_(use_vp9) { |
+VideoEncoderVpx::VideoEncoderVpx(bool use_vp9) |
+ : use_vp9_(use_vp9), encode_unchanged_frame_(false) { |
} |
void VideoEncoderVpx::Configure(const webrtc::DesktopSize& size) { |
@@ -370,9 +362,11 @@ void VideoEncoderVpx::Configure(const webrtc::DesktopSize& size) { |
FreeImageIfMismatched(lossless_color_, size, &image_, &image_buffer_); |
// Initialize active map. |
- active_map_width_ = (size.width() + kMacroBlockSize - 1) / kMacroBlockSize; |
- active_map_height_ = (size.height() + kMacroBlockSize - 1) / kMacroBlockSize; |
- active_map_.reset(new uint8[active_map_width_ * active_map_height_]); |
+ active_map_size_ = webrtc::DesktopSize( |
+ (size.width() + kMacroBlockSize - 1) / kMacroBlockSize, |
+ (size.height() + kMacroBlockSize - 1) / kMacroBlockSize); |
+ active_map_.reset( |
+ new uint8[active_map_size_.width() * active_map_size_.height()]); |
// TODO(wez): Remove this hack once VPX can handle frame size reconfiguration. |
// See https://code.google.com/p/webm/issues/detail?id=912. |
@@ -507,7 +501,8 @@ void VideoEncoderVpx::PrepareImage(const webrtc::DesktopFrame& frame, |
void VideoEncoderVpx::SetActiveMapFromRegion( |
const webrtc::DesktopRegion& updated_region) { |
// Clear active map first. |
- memset(active_map_.get(), 0, active_map_width_ * active_map_height_); |
+ memset(active_map_.get(), 0, |
+ active_map_size_.width() * active_map_size_.height()); |
// Mark updated areas active. |
for (webrtc::DesktopRegion::Iterator r(updated_region); !r.IsAtEnd(); |
@@ -517,14 +512,14 @@ void VideoEncoderVpx::SetActiveMapFromRegion( |
int right = (rect.right() - 1) / kMacroBlockSize; |
int top = rect.top() / kMacroBlockSize; |
int bottom = (rect.bottom() - 1) / kMacroBlockSize; |
- DCHECK_LT(right, active_map_width_); |
- DCHECK_LT(bottom, active_map_height_); |
+ DCHECK_LT(right, active_map_size_.width()); |
+ DCHECK_LT(bottom, active_map_size_.height()); |
- uint8* map = active_map_.get() + top * active_map_width_; |
+ uint8* map = active_map_.get() + top * active_map_size_.width(); |
for (int y = top; y <= bottom; ++y) { |
for (int x = left; x <= right; ++x) |
map[x] = 1; |
- map += active_map_width_; |
+ map += active_map_size_.width(); |
} |
} |
} |
@@ -532,11 +527,11 @@ void VideoEncoderVpx::SetActiveMapFromRegion( |
void VideoEncoderVpx::UpdateRegionFromActiveMap( |
webrtc::DesktopRegion* updated_region) { |
const uint8* map = active_map_.get(); |
- for (int y = 0; y < active_map_height_; ++y) { |
- for (int x0 = 0; x0 < active_map_width_;) { |
+ for (int y = 0; y < active_map_size_.height(); ++y) { |
+ for (int x0 = 0; x0 < active_map_size_.width();) { |
int x1 = x0; |
- for (; x1 < active_map_width_; ++x1) { |
- if (map[y * active_map_width_ + x1] == 0) |
+ for (; x1 < active_map_size_.width(); ++x1) { |
+ if (map[y * active_map_size_.width() + x1] == 0) |
break; |
} |
if (x1 > x0) { |