From 1c90cab2cac820e1aa1f62ed332b1be1e9e44c95 Mon Sep 17 00:00:00 2001 From: Ilya Nikolaevskiy Date: Thu, 7 Mar 2019 15:30:58 +0100 Subject: [PATCH] Fix UpdateRect handling for native buffers in VideoStreamEncoder In Chrome we sometimes get frames with native handlers all the time. To enable variable frame rate we need to trust at least empty updates. Also, trust empty update rect when scaling. Bug: webrtc:10310 Change-Id: I6087b66d5e6138290a7c143f85ba9bc427ae40a1 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/126223 Reviewed-by: Johannes Kron Commit-Queue: Ilya Nikolaevskiy Cr-Commit-Position: refs/heads/master@{#27021} --- video/video_stream_encoder.cc | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc index 9572512002..98ed015916 100644 --- a/video/video_stream_encoder.cc +++ b/video/video_stream_encoder.cc @@ -1177,7 +1177,12 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame, } else { cropped_buffer->ScaleFrom( *video_frame.video_frame_buffer()->ToI420().get()); - update_rect = VideoFrame::UpdateRect{0, 0, cropped_width, cropped_height}; + if (!update_rect.IsEmpty()) { + // Since we can't reason about pixels after scaling, we invalidate whole + // picture, if anything changed. + update_rect = + VideoFrame::UpdateRect{0, 0, cropped_width, cropped_height}; + } } out_frame = VideoFrame::Builder() .set_video_frame_buffer(cropped_buffer) @@ -1250,15 +1255,22 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame, return; } - // UpdatedRect is not propagated because buffer was converted, - // therefore we can't guarantee that pixels outside of UpdateRect didn't - // change comparing to the previous frame. + // UpdatedRect is reset to full update if it's not empty, because buffer was + // converted, therefore we can't guarantee that pixels outside of UpdateRect + // didn't change comparing to the previous frame. + VideoFrame::UpdateRect update_rect = + out_frame.update_rect().IsEmpty() + ? out_frame.update_rect() + : VideoFrame::UpdateRect{0, 0, out_frame.width(), + out_frame.height()}; + out_frame = VideoFrame::Builder() .set_video_frame_buffer(converted_buffer) .set_timestamp_rtp(out_frame.timestamp()) .set_timestamp_ms(out_frame.render_time_ms()) .set_rotation(out_frame.rotation()) .set_id(out_frame.id()) + .set_update_rect(update_rect) .build(); }