Index: webrtc/common_video/video_render_frames.cc |
diff --git a/webrtc/common_video/video_render_frames.cc b/webrtc/common_video/video_render_frames.cc |
index c6b109c2e91afdc4fef169283025cd045f162b42..444347d205cab68ae69f95e20b0108617ccad61f 100644 |
--- a/webrtc/common_video/video_render_frames.cc |
+++ b/webrtc/common_video/video_render_frames.cc |
@@ -10,6 +10,8 @@ |
#include "webrtc/common_video/video_render_frames.h" |
+#include <utility> |
+ |
#include "webrtc/base/logging.h" |
#include "webrtc/base/timeutils.h" |
#include "webrtc/modules/include/module_common_types.h" |
@@ -17,6 +19,10 @@ |
namespace webrtc { |
namespace { |
+// Don't render frames with timestamp older than 500ms from now. |
+const int kOldRenderTimestampMS = 500; |
+// Don't render frames with timestamp more than 10s into the future. |
+const int kFutureRenderTimestampMS = 10000; |
const uint32_t kEventMaxWaitTimeMs = 200; |
const uint32_t kMinRenderDelayMs = 10; |
@@ -33,13 +39,13 @@ uint32_t EnsureValidRenderDelay(uint32_t render_delay) { |
VideoRenderFrames::VideoRenderFrames(uint32_t render_delay_ms) |
: render_delay_ms_(EnsureValidRenderDelay(render_delay_ms)) {} |
-int32_t VideoRenderFrames::AddFrame(const VideoFrame& new_frame) { |
+int32_t VideoRenderFrames::AddFrame(VideoFrame&& new_frame) { |
const int64_t time_now = rtc::TimeMillis(); |
// Drop old frames only when there are other frames in the queue, otherwise, a |
// really slow system never renders any frames. |
if (!incoming_frames_.empty() && |
- new_frame.render_time_ms() + KOldRenderTimestampMS < time_now) { |
+ new_frame.render_time_ms() + kOldRenderTimestampMS < time_now) { |
WEBRTC_TRACE(kTraceWarning, |
kTraceVideoRenderer, |
-1, |
@@ -49,14 +55,25 @@ int32_t VideoRenderFrames::AddFrame(const VideoFrame& new_frame) { |
return -1; |
} |
- if (new_frame.render_time_ms() > time_now + KFutureRenderTimestampMS) { |
+ if (new_frame.render_time_ms() > time_now + kFutureRenderTimestampMS) { |
WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, -1, |
"%s: frame too long into the future, timestamp=%u.", |
__FUNCTION__, new_frame.timestamp()); |
return -1; |
} |
- incoming_frames_.push_back(new_frame); |
+ if (new_frame.render_time_ms() < last_render_time_ms_) { |
+ WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, -1, |
+ "%s: frame scheduled out of order, render_time=%u, latest=%u.", |
+ __FUNCTION__, new_frame.render_time_ms(), |
+ last_render_time_ms_); |
+ // TODO(mflodman): Decide what to do when this happens. |
+ // See bug: https://bugs.chromium.org/p/webrtc/issues/detail?id=7253 |
+ } |
+ |
+ last_render_time_ms_ = new_frame.render_time_ms(); |
+ incoming_frames_.emplace_back(std::move(new_frame)); |
+ |
if (incoming_frames_.size() > kMaxIncomingFramesBeforeLogged) |
LOG(LS_WARNING) << "Stored incoming frames: " << incoming_frames_.size(); |
return static_cast<int32_t>(incoming_frames_.size()); |
@@ -66,7 +83,8 @@ rtc::Optional<VideoFrame> VideoRenderFrames::FrameToRender() { |
rtc::Optional<VideoFrame> render_frame; |
// Get the newest frame that can be released for rendering. |
while (!incoming_frames_.empty() && TimeToNextFrameRelease() <= 0) { |
- render_frame = rtc::Optional<VideoFrame>(incoming_frames_.front()); |
+ render_frame = |
+ rtc::Optional<VideoFrame>(std::move(incoming_frames_.front())); |
incoming_frames_.pop_front(); |
} |
return render_frame; |
@@ -82,4 +100,8 @@ uint32_t VideoRenderFrames::TimeToNextFrameRelease() { |
return time_to_release < 0 ? 0u : static_cast<uint32_t>(time_to_release); |
} |
+bool VideoRenderFrames::HasPendingFrames() const { |
+ return !incoming_frames_.empty(); |
+} |
+ |
} // namespace webrtc |