| OLD | NEW |
| 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 <cstring> | 8 #include <cstring> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/trace_event/trace_event.h" | 12 #include "base/trace_event/trace_event.h" |
| 13 #include "media/cast/cast_defines.h" | 13 #include "media/cast/cast_defines.h" |
| 14 #include "media/cast/net/cast_transport_config.h" | 14 #include "media/cast/net/cast_transport_config.h" |
| 15 #include "media/cast/sender/performance_metrics_overlay.h" | 15 #include "media/cast/sender/performance_metrics_overlay.h" |
| 16 #include "media/cast/sender/video_encoder.h" | 16 #include "media/cast/sender/video_encoder.h" |
| 17 | 17 |
| 18 namespace media { | 18 namespace media { |
| 19 namespace cast { | 19 namespace cast { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 // The following two constants are used to adjust the target | 23 // The following two constants are used to adjust the target |
| 24 // playout delay (when allowed). They were calculated using | 24 // playout delay (when allowed). They were calculated using |
| 25 // a combination of cast_benchmark runs and manual testing. | 25 // a combination of cast_benchmark runs and manual testing. |
| 26 // | 26 // |
| 27 // This is how many round trips we think we need on the network. | 27 // This is how many round trips we think we need on the network. |
| 28 const int kRoundTripsNeeded = 4; | 28 const int kRoundTripsNeeded = 4; |
| 29 |
| 29 // This is an estimate of all the the constant time needed independent of | 30 // This is an estimate of all the the constant time needed independent of |
| 30 // network quality (e.g., additional time that accounts for encode and decode | 31 // network quality (e.g., additional time that accounts for encode and decode |
| 31 // time). | 32 // time). |
| 32 const int kConstantTimeMs = 75; | 33 const int kConstantTimeMs = 75; |
| 33 | 34 |
| 35 // The target maximum utilization of the encoder and network resources. This is |
| 36 // used to attenuate the actual measured utilization values in order to provide |
| 37 // "breathing room" (i.e., to ensure there will be sufficient CPU and bandwidth |
| 38 // available to handle the occasional more-complex frames). |
| 39 const int kTargetUtilizationPercentage = 75; |
| 40 |
| 34 // Extract capture begin/end timestamps from |video_frame|'s metadata and log | 41 // Extract capture begin/end timestamps from |video_frame|'s metadata and log |
| 35 // it. | 42 // it. |
| 36 void LogVideoCaptureTimestamps(const CastEnvironment& cast_environment, | 43 void LogVideoCaptureTimestamps(const CastEnvironment& cast_environment, |
| 37 const media::VideoFrame& video_frame, | 44 const media::VideoFrame& video_frame, |
| 38 RtpTimestamp rtp_timestamp) { | 45 RtpTimestamp rtp_timestamp) { |
| 39 base::TimeTicks capture_begin_time; | 46 base::TimeTicks capture_begin_time; |
| 40 base::TimeTicks capture_end_time; | 47 base::TimeTicks capture_end_time; |
| 41 if (!video_frame.metadata()->GetTimeTicks( | 48 if (!video_frame.metadata()->GetTimeTicks( |
| 42 media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, &capture_begin_time) || | 49 media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, &capture_begin_time) || |
| 43 !video_frame.metadata()->GetTimeTicks( | 50 !video_frame.metadata()->GetTimeTicks( |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 frames_in_encoder_ + 1, | 208 frames_in_encoder_ + 1, |
| 202 last_reported_deadline_utilization_, | 209 last_reported_deadline_utilization_, |
| 203 last_reported_lossy_utilization_, | 210 last_reported_lossy_utilization_, |
| 204 video_frame.get()); | 211 video_frame.get()); |
| 205 | 212 |
| 206 if (video_encoder_->EncodeVideoFrame( | 213 if (video_encoder_->EncodeVideoFrame( |
| 207 video_frame, | 214 video_frame, |
| 208 reference_time, | 215 reference_time, |
| 209 base::Bind(&VideoSender::OnEncodedVideoFrame, | 216 base::Bind(&VideoSender::OnEncodedVideoFrame, |
| 210 weak_factory_.GetWeakPtr(), | 217 weak_factory_.GetWeakPtr(), |
| 218 video_frame, |
| 211 bitrate))) { | 219 bitrate))) { |
| 212 frames_in_encoder_++; | 220 frames_in_encoder_++; |
| 213 duration_in_encoder_ += duration_added_by_next_frame; | 221 duration_in_encoder_ += duration_added_by_next_frame; |
| 214 last_enqueued_frame_rtp_timestamp_ = rtp_timestamp; | 222 last_enqueued_frame_rtp_timestamp_ = rtp_timestamp; |
| 215 last_enqueued_frame_reference_time_ = reference_time; | 223 last_enqueued_frame_reference_time_ = reference_time; |
| 216 } else { | 224 } else { |
| 217 VLOG(1) << "Encoder rejected a frame. Skipping..."; | 225 VLOG(1) << "Encoder rejected a frame. Skipping..."; |
| 218 } | 226 } |
| 219 } | 227 } |
| 220 | 228 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 234 } else { | 242 } else { |
| 235 return duration_in_encoder_; | 243 return duration_in_encoder_; |
| 236 } | 244 } |
| 237 } | 245 } |
| 238 | 246 |
| 239 void VideoSender::OnAck(uint32 frame_id) { | 247 void VideoSender::OnAck(uint32 frame_id) { |
| 240 video_encoder_->LatestFrameIdToReference(frame_id); | 248 video_encoder_->LatestFrameIdToReference(frame_id); |
| 241 } | 249 } |
| 242 | 250 |
| 243 void VideoSender::OnEncodedVideoFrame( | 251 void VideoSender::OnEncodedVideoFrame( |
| 252 const scoped_refptr<media::VideoFrame>& video_frame, |
| 244 int encoder_bitrate, | 253 int encoder_bitrate, |
| 245 scoped_ptr<SenderEncodedFrame> encoded_frame) { | 254 scoped_ptr<SenderEncodedFrame> encoded_frame) { |
| 246 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 255 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 247 | 256 |
| 248 frames_in_encoder_--; | 257 frames_in_encoder_--; |
| 249 DCHECK_GE(frames_in_encoder_, 0); | 258 DCHECK_GE(frames_in_encoder_, 0); |
| 250 | 259 |
| 251 duration_in_encoder_ = | 260 duration_in_encoder_ = |
| 252 last_enqueued_frame_reference_time_ - encoded_frame->reference_time; | 261 last_enqueued_frame_reference_time_ - encoded_frame->reference_time; |
| 253 | 262 |
| 254 last_reported_deadline_utilization_ = encoded_frame->deadline_utilization; | 263 last_reported_deadline_utilization_ = encoded_frame->deadline_utilization; |
| 255 last_reported_lossy_utilization_ = encoded_frame->lossy_utilization; | 264 last_reported_lossy_utilization_ = encoded_frame->lossy_utilization; |
| 256 // TODO(miu): Plumb-in a utilization feedback signal back to the producer of | 265 |
| 257 // the video frames. http://crbug.com/156767 | 266 // Report the resource utilization for processing this frame. Take the |
| 267 // greater of the two utilization values and attenuate them such that the |
| 268 // target utilization is reported as the maximum sustainable amount. |
| 269 const double attenuated_utilization = |
| 270 std::max(last_reported_deadline_utilization_, |
| 271 last_reported_lossy_utilization_) / |
| 272 (kTargetUtilizationPercentage / 100.0); |
| 273 if (attenuated_utilization >= 0.0) { |
| 274 // Key frames are artificially capped to 1.0 because their actual |
| 275 // utilization is atypical compared to the other frames in the stream, and |
| 276 // this can misguide the producer of the input video frames. |
| 277 video_frame->metadata()->SetDouble( |
| 278 media::VideoFrameMetadata::RESOURCE_UTILIZATION, |
| 279 encoded_frame->dependency == EncodedFrame::KEY ? |
| 280 std::min(1.0, attenuated_utilization) : attenuated_utilization); |
| 281 } |
| 258 | 282 |
| 259 SendEncodedFrame(encoder_bitrate, encoded_frame.Pass()); | 283 SendEncodedFrame(encoder_bitrate, encoded_frame.Pass()); |
| 260 } | 284 } |
| 261 | 285 |
| 262 } // namespace cast | 286 } // namespace cast |
| 263 } // namespace media | 287 } // namespace media |
| OLD | NEW |