Chromium Code Reviews| 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 <stdint.h> | 7 #include <stdint.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <cmath> | 9 #include <cmath> |
| 10 #include <cstring> | 10 #include <cstring> |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 34 // network quality (e.g., additional time that accounts for encode and decode | 34 // network quality (e.g., additional time that accounts for encode and decode |
| 35 // time). | 35 // time). |
| 36 const int kConstantTimeMs = 75; | 36 const int kConstantTimeMs = 75; |
| 37 | 37 |
| 38 // The target maximum utilization of the encoder and network resources. This is | 38 // The target maximum utilization of the encoder and network resources. This is |
| 39 // used to attenuate the actual measured utilization values in order to provide | 39 // used to attenuate the actual measured utilization values in order to provide |
| 40 // "breathing room" (i.e., to ensure there will be sufficient CPU and bandwidth | 40 // "breathing room" (i.e., to ensure there will be sufficient CPU and bandwidth |
| 41 // available to handle the occasional more-complex frames). | 41 // available to handle the occasional more-complex frames). |
| 42 const int kTargetUtilizationPercentage = 75; | 42 const int kTargetUtilizationPercentage = 75; |
| 43 | 43 |
| 44 // This is the minimum duration in milliseconds that the sender will response | |
|
Irfan
2016/02/29 16:01:23
will respond
xjz
2016/02/29 19:48:58
Done.
| |
| 45 // to muliple Pli messages. | |
| 46 const int kMinPliResolveIntervalMs = 500; | |
|
Irfan
2016/02/29 16:01:23
may be: kMinPliResponseIntervaleMs
xjz
2016/02/29 19:48:58
Done.
| |
| 47 | |
| 44 // Extract capture begin/end timestamps from |video_frame|'s metadata and log | 48 // Extract capture begin/end timestamps from |video_frame|'s metadata and log |
| 45 // it. | 49 // it. |
| 46 void LogVideoCaptureTimestamps(CastEnvironment* cast_environment, | 50 void LogVideoCaptureTimestamps(CastEnvironment* cast_environment, |
| 47 const media::VideoFrame& video_frame, | 51 const media::VideoFrame& video_frame, |
| 48 RtpTimeTicks rtp_timestamp) { | 52 RtpTimeTicks rtp_timestamp) { |
| 49 scoped_ptr<FrameEvent> capture_begin_event(new FrameEvent()); | 53 scoped_ptr<FrameEvent> capture_begin_event(new FrameEvent()); |
| 50 capture_begin_event->type = FRAME_CAPTURE_BEGIN; | 54 capture_begin_event->type = FRAME_CAPTURE_BEGIN; |
| 51 capture_begin_event->media_type = VIDEO_EVENT; | 55 capture_begin_event->media_type = VIDEO_EVENT; |
| 52 capture_begin_event->rtp_timestamp = rtp_timestamp; | 56 capture_begin_event->rtp_timestamp = rtp_timestamp; |
| 53 | 57 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 } | 131 } |
| 128 | 132 |
| 129 media::cast::CastTransportRtpConfig transport_config; | 133 media::cast::CastTransportRtpConfig transport_config; |
| 130 transport_config.ssrc = video_config.ssrc; | 134 transport_config.ssrc = video_config.ssrc; |
| 131 transport_config.feedback_ssrc = video_config.receiver_ssrc; | 135 transport_config.feedback_ssrc = video_config.receiver_ssrc; |
| 132 transport_config.rtp_payload_type = video_config.rtp_payload_type; | 136 transport_config.rtp_payload_type = video_config.rtp_payload_type; |
| 133 transport_config.aes_key = video_config.aes_key; | 137 transport_config.aes_key = video_config.aes_key; |
| 134 transport_config.aes_iv_mask = video_config.aes_iv_mask; | 138 transport_config.aes_iv_mask = video_config.aes_iv_mask; |
| 135 | 139 |
| 136 transport_sender->InitializeVideo( | 140 transport_sender->InitializeVideo( |
| 137 transport_config, | 141 transport_config, base::Bind(&VideoSender::OnReceivedCastFeedback, |
| 138 base::Bind(&VideoSender::OnReceivedCastFeedback, | 142 weak_factory_.GetWeakPtr()), |
| 143 base::Bind(&VideoSender::OnMeasuredRoundTripTime, | |
| 139 weak_factory_.GetWeakPtr()), | 144 weak_factory_.GetWeakPtr()), |
| 140 base::Bind(&VideoSender::OnMeasuredRoundTripTime, | 145 base::Bind(&VideoSender::OnReceivedPli, weak_factory_.GetWeakPtr())); |
| 141 weak_factory_.GetWeakPtr())); | |
| 142 } | 146 } |
| 143 | 147 |
| 144 VideoSender::~VideoSender() { | 148 VideoSender::~VideoSender() { |
| 145 } | 149 } |
| 146 | 150 |
| 147 void VideoSender::InsertRawVideoFrame( | 151 void VideoSender::InsertRawVideoFrame( |
| 148 const scoped_refptr<media::VideoFrame>& video_frame, | 152 const scoped_refptr<media::VideoFrame>& video_frame, |
| 149 const base::TimeTicks& reference_time) { | 153 const base::TimeTicks& reference_time) { |
| 150 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 154 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 151 | 155 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 185 (rtp_timestamp <= last_enqueued_frame_rtp_timestamp_ || | 189 (rtp_timestamp <= last_enqueued_frame_rtp_timestamp_ || |
| 186 reference_time <= last_enqueued_frame_reference_time_)) { | 190 reference_time <= last_enqueued_frame_reference_time_)) { |
| 187 VLOG(1) << "Dropping video frame: RTP or reference time did not increase."; | 191 VLOG(1) << "Dropping video frame: RTP or reference time did not increase."; |
| 188 TRACE_EVENT_INSTANT2("cast.stream", "Video Frame Drop", | 192 TRACE_EVENT_INSTANT2("cast.stream", "Video Frame Drop", |
| 189 TRACE_EVENT_SCOPE_THREAD, | 193 TRACE_EVENT_SCOPE_THREAD, |
| 190 "rtp_timestamp", rtp_timestamp.lower_32_bits(), | 194 "rtp_timestamp", rtp_timestamp.lower_32_bits(), |
| 191 "reason", "time did not increase"); | 195 "reason", "time did not increase"); |
| 192 return; | 196 return; |
| 193 } | 197 } |
| 194 | 198 |
| 199 // Request a key frame when received a Pli message, and it has been passed | |
| 200 // more than |kMinPliResolveIntervalMs| milliseconds from the last key frame | |
| 201 // request sent to encoder. | |
| 202 if (picture_lost_at_receiver_) { | |
| 203 if (last_attempt_to_resolve_picture_loss_.is_null() || | |
| 204 ((reference_time - last_attempt_to_resolve_picture_loss_) | |
| 205 .InMilliseconds() > kMinPliResolveIntervalMs)) { | |
| 206 video_encoder_->GenerateKeyFrame(); | |
| 207 last_attempt_to_resolve_picture_loss_ = reference_time; | |
| 208 } | |
| 209 } | |
| 210 | |
| 195 // Two video frames are needed to compute the exact media duration added by | 211 // Two video frames are needed to compute the exact media duration added by |
| 196 // the next frame. If there are no frames in the encoder, compute a guess | 212 // the next frame. If there are no frames in the encoder, compute a guess |
| 197 // based on the configured |max_frame_rate_|. Any error introduced by this | 213 // based on the configured |max_frame_rate_|. Any error introduced by this |
| 198 // guess will be eliminated when |duration_in_encoder_| is updated in | 214 // guess will be eliminated when |duration_in_encoder_| is updated in |
| 199 // OnEncodedVideoFrame(). | 215 // OnEncodedVideoFrame(). |
| 200 const base::TimeDelta duration_added_by_next_frame = frames_in_encoder_ > 0 ? | 216 const base::TimeDelta duration_added_by_next_frame = frames_in_encoder_ > 0 ? |
| 201 reference_time - last_enqueued_frame_reference_time_ : | 217 reference_time - last_enqueued_frame_reference_time_ : |
| 202 base::TimeDelta::FromSecondsD(1.0 / max_frame_rate_); | 218 base::TimeDelta::FromSecondsD(1.0 / max_frame_rate_); |
| 203 | 219 |
| 204 if (ShouldDropNextFrame(duration_added_by_next_frame)) { | 220 if (ShouldDropNextFrame(duration_added_by_next_frame)) { |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 331 media::VideoFrameMetadata::RESOURCE_UTILIZATION, | 347 media::VideoFrameMetadata::RESOURCE_UTILIZATION, |
| 332 encoded_frame->dependency == EncodedFrame::KEY ? | 348 encoded_frame->dependency == EncodedFrame::KEY ? |
| 333 std::min(1.0, attenuated_utilization) : attenuated_utilization); | 349 std::min(1.0, attenuated_utilization) : attenuated_utilization); |
| 334 } | 350 } |
| 335 | 351 |
| 336 SendEncodedFrame(encoder_bitrate, std::move(encoded_frame)); | 352 SendEncodedFrame(encoder_bitrate, std::move(encoded_frame)); |
| 337 } | 353 } |
| 338 | 354 |
| 339 } // namespace cast | 355 } // namespace cast |
| 340 } // namespace media | 356 } // namespace media |
| OLD | NEW |