1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/common_video/video_render_frames.h" 12 13 #include <assert.h> 14 15 #include "webrtc/modules/include/module_common_types.h" 16 #include "webrtc/system_wrappers/include/tick_util.h" 17 #include "webrtc/system_wrappers/include/trace.h" 18 19 namespace webrtc { 20 21 const uint32_t KEventMaxWaitTimeMs = 200; 22 const uint32_t kMinRenderDelayMs = 10; 23 const uint32_t kMaxRenderDelayMs = 500; 24 25 VideoRenderFrames::VideoRenderFrames() 26 : render_delay_ms_(10) { 27 } 28 29 int32_t VideoRenderFrames::AddFrame(const VideoFrame& new_frame) { 30 const int64_t time_now = TickTime::MillisecondTimestamp(); 31 32 // Drop old frames only when there are other frames in the queue, otherwise, a 33 // really slow system never renders any frames. 34 if (!incoming_frames_.empty() && 35 new_frame.render_time_ms() + KOldRenderTimestampMS < time_now) { 36 WEBRTC_TRACE(kTraceWarning, 37 kTraceVideoRenderer, 38 -1, 39 "%s: too old frame, timestamp=%u.", 40 __FUNCTION__, 41 new_frame.timestamp()); 42 return -1; 43 } 44 45 if (new_frame.render_time_ms() > time_now + KFutureRenderTimestampMS) { 46 WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, -1, 47 "%s: frame too long into the future, timestamp=%u.", 48 __FUNCTION__, new_frame.timestamp()); 49 return -1; 50 } 51 52 incoming_frames_.push_back(new_frame); 53 return static_cast<int32_t>(incoming_frames_.size()); 54 } 55 56 VideoFrame VideoRenderFrames::FrameToRender() { 57 VideoFrame render_frame; 58 // Get the newest frame that can be released for rendering. 59 while (!incoming_frames_.empty() && TimeToNextFrameRelease() <= 0) { 60 render_frame = incoming_frames_.front(); 61 incoming_frames_.pop_front(); 62 } 63 return render_frame; 64 } 65 66 int32_t VideoRenderFrames::ReleaseAllFrames() { 67 incoming_frames_.clear(); 68 return 0; 69 } 70 71 uint32_t VideoRenderFrames::TimeToNextFrameRelease() { 72 if (incoming_frames_.empty()) { 73 return KEventMaxWaitTimeMs; 74 } 75 const int64_t time_to_release = incoming_frames_.front().render_time_ms() - 76 render_delay_ms_ - 77 TickTime::MillisecondTimestamp(); 78 return time_to_release < 0 ? 0u : static_cast<uint32_t>(time_to_release); 79 } 80 81 int32_t VideoRenderFrames::SetRenderDelay( 82 const uint32_t render_delay) { 83 if (render_delay < kMinRenderDelayMs || 84 render_delay > kMaxRenderDelayMs) { 85 WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, 86 -1, "%s(%d): Invalid argument.", __FUNCTION__, 87 render_delay); 88 return -1; 89 } 90 91 render_delay_ms_ = render_delay; 92 return 0; 93 } 94 95 } // namespace webrtc 96