Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: media/cast/sender/video_sender.cc

Issue 1484403002: cast: Support for low-latency interactive mode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/cast/sender/video_sender.h" 5 #include "media/cast/sender/video_sender.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <cstring> 9 #include <cstring>
10 10
(...skipping 21 matching lines...) Expand all
32 // network quality (e.g., additional time that accounts for encode and decode 32 // network quality (e.g., additional time that accounts for encode and decode
33 // time). 33 // time).
34 const int kConstantTimeMs = 75; 34 const int kConstantTimeMs = 75;
35 35
36 // The target maximum utilization of the encoder and network resources. This is 36 // The target maximum utilization of the encoder and network resources. This is
37 // used to attenuate the actual measured utilization values in order to provide 37 // used to attenuate the actual measured utilization values in order to provide
38 // "breathing room" (i.e., to ensure there will be sufficient CPU and bandwidth 38 // "breathing room" (i.e., to ensure there will be sufficient CPU and bandwidth
39 // available to handle the occasional more-complex frames). 39 // available to handle the occasional more-complex frames).
40 const int kTargetUtilizationPercentage = 75; 40 const int kTargetUtilizationPercentage = 75;
41 41
42 // Minimum number of user interactions before we consider the user to be in
43 // interactive mode. The goal is to prevent user interactions to launch
44 // animated content from causing target playout time flip-flop.
45 const int kMinUserInteractionsForInteractiveMode = 5;
46
42 // Extract capture begin/end timestamps from |video_frame|'s metadata and log 47 // Extract capture begin/end timestamps from |video_frame|'s metadata and log
43 // it. 48 // it.
44 void LogVideoCaptureTimestamps(CastEnvironment* cast_environment, 49 void LogVideoCaptureTimestamps(CastEnvironment* cast_environment,
45 const media::VideoFrame& video_frame, 50 const media::VideoFrame& video_frame,
46 RtpTimestamp rtp_timestamp) { 51 RtpTimestamp rtp_timestamp) {
47 scoped_ptr<FrameEvent> capture_begin_event(new FrameEvent()); 52 scoped_ptr<FrameEvent> capture_begin_event(new FrameEvent());
48 capture_begin_event->type = FRAME_CAPTURE_BEGIN; 53 capture_begin_event->type = FRAME_CAPTURE_BEGIN;
49 capture_begin_event->media_type = VIDEO_EVENT; 54 capture_begin_event->media_type = VIDEO_EVENT;
50 capture_begin_event->rtp_timestamp = rtp_timestamp; 55 capture_begin_event->rtp_timestamp = rtp_timestamp;
51 56
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 video_config.use_external_encoder 103 video_config.use_external_encoder
99 ? NewFixedCongestionControl( 104 ? NewFixedCongestionControl(
100 (video_config.min_bitrate + video_config.max_bitrate) / 2) 105 (video_config.min_bitrate + video_config.max_bitrate) / 2)
101 : NewAdaptiveCongestionControl(cast_environment->Clock(), 106 : NewAdaptiveCongestionControl(cast_environment->Clock(),
102 video_config.max_bitrate, 107 video_config.max_bitrate,
103 video_config.min_bitrate, 108 video_config.min_bitrate,
104 video_config.max_frame_rate)), 109 video_config.max_frame_rate)),
105 frames_in_encoder_(0), 110 frames_in_encoder_(0),
106 last_bitrate_(0), 111 last_bitrate_(0),
107 playout_delay_change_cb_(playout_delay_change_cb), 112 playout_delay_change_cb_(playout_delay_change_cb),
113 animation_content_(true),
114 user_interaction_(false),
115 user_interaction_count_(0),
116 interactive_mode_(false),
108 last_reported_deadline_utilization_(-1.0), 117 last_reported_deadline_utilization_(-1.0),
109 last_reported_lossy_utilization_(-1.0), 118 last_reported_lossy_utilization_(-1.0),
110 weak_factory_(this) { 119 weak_factory_(this) {
111 video_encoder_ = VideoEncoder::Create( 120 video_encoder_ = VideoEncoder::Create(
112 cast_environment_, 121 cast_environment_,
113 video_config, 122 video_config,
114 status_change_cb, 123 status_change_cb,
115 create_vea_cb, 124 create_vea_cb,
116 create_video_encode_mem_cb); 125 create_video_encode_mem_cb);
117 if (!video_encoder_) { 126 if (!video_encoder_) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 LogVideoCaptureTimestamps(cast_environment_.get(), *video_frame, 163 LogVideoCaptureTimestamps(cast_environment_.get(), *video_frame,
155 rtp_timestamp); 164 rtp_timestamp);
156 165
157 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc 166 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc
158 TRACE_EVENT_INSTANT2( 167 TRACE_EVENT_INSTANT2(
159 "cast_perf_test", "InsertRawVideoFrame", 168 "cast_perf_test", "InsertRawVideoFrame",
160 TRACE_EVENT_SCOPE_THREAD, 169 TRACE_EVENT_SCOPE_THREAD,
161 "timestamp", reference_time.ToInternalValue(), 170 "timestamp", reference_time.ToInternalValue(),
162 "rtp_timestamp", rtp_timestamp); 171 "rtp_timestamp", rtp_timestamp);
163 172
173 bool prev_user_interaction = user_interaction_;
174 if (video_frame->metadata()->GetBoolean(VideoFrameMetadata::ANIMATION_CONTENT,
175 &animation_content_) &&
176 video_frame->metadata()->GetBoolean(VideoFrameMetadata::USER_INTERACTION,
177 &user_interaction_)) {
178 if (user_interaction_ && !prev_user_interaction) {
179 user_interaction_count_++;
miu 2015/12/01 21:15:27 IIUC, this is counting the number of frames where
Irfan 2015/12/02 22:32:44 This has moved to capture side now.
180 }
181 if (user_interaction_count_ > kMinUserInteractionsForInteractiveMode &&
182 !animation_content_ && !interactive_mode_) {
miu 2015/12/01 21:15:27 Perhaps we should only consider the "user interact
Irfan 2015/12/02 22:37:55 As discussed f2f, I think we should be more conser
183 interactive_mode_ = true;
184 VLOG(1) << "Interactive mode playout time "
185 << media::cast::kInteractiveModeStartPlayoutTimeMs;
186 playout_delay_change_cb_.Run(base::TimeDelta::FromMilliseconds(
187 media::cast::kInteractiveModeStartPlayoutTimeMs));
188 } else if (animation_content_) {
189 // Reset user interactions when animating content is playing.
190 user_interaction_count_ = 0;
191 interactive_mode_ = false;
192 }
193 }
194
miu 2015/12/01 21:15:27 BTW--What about audio? If we change video's playo
Irfan 2015/12/02 22:32:44 This already works as you describe :-)
164 // Drop the frame if either its RTP or reference timestamp is not an increase 195 // Drop the frame if either its RTP or reference timestamp is not an increase
165 // over the last frame's. This protects: 1) the duration calculations that 196 // over the last frame's. This protects: 1) the duration calculations that
166 // assume timestamps are monotonically non-decreasing, and 2) assumptions made 197 // assume timestamps are monotonically non-decreasing, and 2) assumptions made
167 // deeper in the implementation where each frame's RTP timestamp needs to be 198 // deeper in the implementation where each frame's RTP timestamp needs to be
168 // unique. 199 // unique.
169 if (!last_enqueued_frame_reference_time_.is_null() && 200 if (!last_enqueued_frame_reference_time_.is_null() &&
170 (!IsNewerRtpTimestamp(rtp_timestamp, 201 (!IsNewerRtpTimestamp(rtp_timestamp,
171 last_enqueued_frame_rtp_timestamp_) || 202 last_enqueued_frame_rtp_timestamp_) ||
172 reference_time <= last_enqueued_frame_reference_time_)) { 203 reference_time <= last_enqueued_frame_reference_time_)) {
173 VLOG(1) << "Dropping video frame: RTP or reference time did not increase."; 204 VLOG(1) << "Dropping video frame: RTP or reference time did not increase.";
(...skipping 11 matching lines...) Expand all
185 // OnEncodedVideoFrame(). 216 // OnEncodedVideoFrame().
186 const base::TimeDelta duration_added_by_next_frame = frames_in_encoder_ > 0 ? 217 const base::TimeDelta duration_added_by_next_frame = frames_in_encoder_ > 0 ?
187 reference_time - last_enqueued_frame_reference_time_ : 218 reference_time - last_enqueued_frame_reference_time_ :
188 base::TimeDelta::FromSecondsD(1.0 / max_frame_rate_); 219 base::TimeDelta::FromSecondsD(1.0 / max_frame_rate_);
189 220
190 if (ShouldDropNextFrame(duration_added_by_next_frame)) { 221 if (ShouldDropNextFrame(duration_added_by_next_frame)) {
191 base::TimeDelta new_target_delay = std::min( 222 base::TimeDelta new_target_delay = std::min(
192 current_round_trip_time_ * kRoundTripsNeeded + 223 current_round_trip_time_ * kRoundTripsNeeded +
193 base::TimeDelta::FromMilliseconds(kConstantTimeMs), 224 base::TimeDelta::FromMilliseconds(kConstantTimeMs),
194 max_playout_delay_); 225 max_playout_delay_);
195 if (new_target_delay > target_playout_delay_) { 226 // In case of interactive mode, we prefer frame drops over increasing
227 // playout time.
228 if (!interactive_mode_ && new_target_delay > target_playout_delay_) {
229 // In case we detect user is no more in an interactive mode and there is
230 // a need to drop a frame, we ensure the playout delay is at-least the
231 // the starting value that is known to work well.
232 // This is intentended to minimize freeze when moving from an interactive
233 // session to watching animating content while being limited by end-to-end
234 // delay.
235 VLOG(1) << "Ensure playout time is at least "
236 << media::cast::kNonInteractiveModeStartPlayoutTimeMs;
237 if (new_target_delay.InMilliseconds() <
238 media::cast::kNonInteractiveModeStartPlayoutTimeMs)
239 new_target_delay = base::TimeDelta::FromMilliseconds(
240 kNonInteractiveModeStartPlayoutTimeMs);
196 VLOG(1) << "New target delay: " << new_target_delay.InMilliseconds(); 241 VLOG(1) << "New target delay: " << new_target_delay.InMilliseconds();
197 playout_delay_change_cb_.Run(new_target_delay); 242 playout_delay_change_cb_.Run(new_target_delay);
198 } 243 }
199 244
200 // Some encoder implementations have a frame window for analysis. Since we 245 // Some encoder implementations have a frame window for analysis. Since we
201 // are dropping this frame, unless we instruct the encoder to flush all the 246 // are dropping this frame, unless we instruct the encoder to flush all the
202 // frames that have been enqueued for encoding, frames_in_encoder_ and 247 // frames that have been enqueued for encoding, frames_in_encoder_ and
203 // last_enqueued_frame_reference_time_ will never be updated and we will 248 // last_enqueued_frame_reference_time_ will never be updated and we will
204 // drop every subsequent frame for the rest of the session. 249 // drop every subsequent frame for the rest of the session.
205 video_encoder_->EmitFrames(); 250 video_encoder_->EmitFrames();
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 media::VideoFrameMetadata::RESOURCE_UTILIZATION, 401 media::VideoFrameMetadata::RESOURCE_UTILIZATION,
357 encoded_frame->dependency == EncodedFrame::KEY ? 402 encoded_frame->dependency == EncodedFrame::KEY ?
358 std::min(1.0, attenuated_utilization) : attenuated_utilization); 403 std::min(1.0, attenuated_utilization) : attenuated_utilization);
359 } 404 }
360 405
361 SendEncodedFrame(encoder_bitrate, encoded_frame.Pass()); 406 SendEncodedFrame(encoder_bitrate, encoded_frame.Pass());
362 } 407 }
363 408
364 } // namespace cast 409 } // namespace cast
365 } // namespace media 410 } // namespace media
OLDNEW
« media/cast/sender/frame_sender.cc ('K') | « media/cast/sender/video_sender.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698