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 between two key frame requests. Too many Key | |
| 45 // frames will reduce the dependency among frames, but reduce the picture | |
| 46 // quality as well. | |
| 47 const base::TimeDelta kMinKeyFrameRequestDuration = | |
|
miu
2016/02/26 23:36:07
Static initializer foo: In Chromium code, we can o
xjz
2016/02/27 05:53:32
Done.
| |
| 48 base::TimeDelta::FromMilliseconds(500); | |
| 49 | |
| 44 // Extract capture begin/end timestamps from |video_frame|'s metadata and log | 50 // Extract capture begin/end timestamps from |video_frame|'s metadata and log |
| 45 // it. | 51 // it. |
| 46 void LogVideoCaptureTimestamps(CastEnvironment* cast_environment, | 52 void LogVideoCaptureTimestamps(CastEnvironment* cast_environment, |
| 47 const media::VideoFrame& video_frame, | 53 const media::VideoFrame& video_frame, |
| 48 RtpTimeTicks rtp_timestamp) { | 54 RtpTimeTicks rtp_timestamp) { |
| 49 scoped_ptr<FrameEvent> capture_begin_event(new FrameEvent()); | 55 scoped_ptr<FrameEvent> capture_begin_event(new FrameEvent()); |
| 50 capture_begin_event->type = FRAME_CAPTURE_BEGIN; | 56 capture_begin_event->type = FRAME_CAPTURE_BEGIN; |
| 51 capture_begin_event->media_type = VIDEO_EVENT; | 57 capture_begin_event->media_type = VIDEO_EVENT; |
| 52 capture_begin_event->rtp_timestamp = rtp_timestamp; | 58 capture_begin_event->rtp_timestamp = rtp_timestamp; |
| 53 | 59 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 } | 133 } |
| 128 | 134 |
| 129 media::cast::CastTransportRtpConfig transport_config; | 135 media::cast::CastTransportRtpConfig transport_config; |
| 130 transport_config.ssrc = video_config.ssrc; | 136 transport_config.ssrc = video_config.ssrc; |
| 131 transport_config.feedback_ssrc = video_config.receiver_ssrc; | 137 transport_config.feedback_ssrc = video_config.receiver_ssrc; |
| 132 transport_config.rtp_payload_type = video_config.rtp_payload_type; | 138 transport_config.rtp_payload_type = video_config.rtp_payload_type; |
| 133 transport_config.aes_key = video_config.aes_key; | 139 transport_config.aes_key = video_config.aes_key; |
| 134 transport_config.aes_iv_mask = video_config.aes_iv_mask; | 140 transport_config.aes_iv_mask = video_config.aes_iv_mask; |
| 135 | 141 |
| 136 transport_sender->InitializeVideo( | 142 transport_sender->InitializeVideo( |
| 137 transport_config, | 143 transport_config, base::Bind(&VideoSender::OnReceivedCastFeedback, |
| 138 base::Bind(&VideoSender::OnReceivedCastFeedback, | 144 weak_factory_.GetWeakPtr()), |
| 145 base::Bind(&VideoSender::OnMeasuredRoundTripTime, | |
| 139 weak_factory_.GetWeakPtr()), | 146 weak_factory_.GetWeakPtr()), |
| 140 base::Bind(&VideoSender::OnMeasuredRoundTripTime, | 147 base::Bind(&VideoSender::OnReceivedPli, weak_factory_.GetWeakPtr())); |
| 141 weak_factory_.GetWeakPtr())); | |
| 142 } | 148 } |
| 143 | 149 |
| 144 VideoSender::~VideoSender() { | 150 VideoSender::~VideoSender() { |
| 145 } | 151 } |
| 146 | 152 |
| 147 void VideoSender::InsertRawVideoFrame( | 153 void VideoSender::InsertRawVideoFrame( |
| 148 const scoped_refptr<media::VideoFrame>& video_frame, | 154 const scoped_refptr<media::VideoFrame>& video_frame, |
| 149 const base::TimeTicks& reference_time) { | 155 const base::TimeTicks& reference_time) { |
| 150 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 156 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 151 | 157 |
| 152 if (!video_encoder_) { | 158 if (!video_encoder_) { |
| 153 NOTREACHED(); | 159 NOTREACHED(); |
| 154 return; | 160 return; |
| 155 } | 161 } |
| 156 | 162 |
| 163 // Request a key frame when receive the PLI and it has been passed more than | |
| 164 // |kMinKeyFrameRequestDuration| frome encoding last key frame. | |
| 165 if (picture_lost_at_receiver_) { | |
|
miu
2016/02/26 23:36:07
The client may call InsertRawVideoFrame() several
xjz
2016/02/27 05:53:32
Done.
| |
| 166 base::TimeDelta duration; | |
| 167 if (last_encoded_key_frame_ != base::TimeTicks()) | |
| 168 duration = reference_time - last_encoded_key_frame_; | |
| 169 if (duration > kMinKeyFrameRequestDuration) | |
| 170 video_encoder_->GenerateKeyFrame(); | |
| 171 } | |
| 172 | |
| 157 const RtpTimeTicks rtp_timestamp = | 173 const RtpTimeTicks rtp_timestamp = |
| 158 RtpTimeTicks::FromTimeDelta(video_frame->timestamp(), kVideoFrequency); | 174 RtpTimeTicks::FromTimeDelta(video_frame->timestamp(), kVideoFrequency); |
| 159 LogVideoCaptureTimestamps(cast_environment_.get(), *video_frame, | 175 LogVideoCaptureTimestamps(cast_environment_.get(), *video_frame, |
| 160 rtp_timestamp); | 176 rtp_timestamp); |
| 161 | 177 |
| 162 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc | 178 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc |
| 163 TRACE_EVENT_INSTANT2( | 179 TRACE_EVENT_INSTANT2( |
| 164 "cast_perf_test", "InsertRawVideoFrame", | 180 "cast_perf_test", "InsertRawVideoFrame", |
| 165 TRACE_EVENT_SCOPE_THREAD, | 181 TRACE_EVENT_SCOPE_THREAD, |
| 166 "timestamp", reference_time.ToInternalValue(), | 182 "timestamp", reference_time.ToInternalValue(), |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 299 | 315 |
| 300 void VideoSender::OnEncodedVideoFrame( | 316 void VideoSender::OnEncodedVideoFrame( |
| 301 const scoped_refptr<media::VideoFrame>& video_frame, | 317 const scoped_refptr<media::VideoFrame>& video_frame, |
| 302 int encoder_bitrate, | 318 int encoder_bitrate, |
| 303 scoped_ptr<SenderEncodedFrame> encoded_frame) { | 319 scoped_ptr<SenderEncodedFrame> encoded_frame) { |
| 304 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 320 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 305 | 321 |
| 306 frames_in_encoder_--; | 322 frames_in_encoder_--; |
| 307 DCHECK_GE(frames_in_encoder_, 0); | 323 DCHECK_GE(frames_in_encoder_, 0); |
| 308 | 324 |
| 325 if (encoded_frame->dependency == EncodedFrame::KEY) | |
| 326 last_encoded_key_frame_ = encoded_frame->reference_time; | |
| 327 | |
| 309 duration_in_encoder_ = | 328 duration_in_encoder_ = |
| 310 last_enqueued_frame_reference_time_ - encoded_frame->reference_time; | 329 last_enqueued_frame_reference_time_ - encoded_frame->reference_time; |
| 311 | 330 |
| 312 last_reported_deadline_utilization_ = encoded_frame->deadline_utilization; | 331 last_reported_deadline_utilization_ = encoded_frame->deadline_utilization; |
| 313 last_reported_lossy_utilization_ = encoded_frame->lossy_utilization; | 332 last_reported_lossy_utilization_ = encoded_frame->lossy_utilization; |
| 314 | 333 |
| 315 TRACE_EVENT_ASYNC_END2("cast.stream", "Video Encode", video_frame.get(), | 334 TRACE_EVENT_ASYNC_END2("cast.stream", "Video Encode", video_frame.get(), |
| 316 "deadline_utilization", last_reported_deadline_utilization_, | 335 "deadline_utilization", last_reported_deadline_utilization_, |
| 317 "lossy_utilization", last_reported_lossy_utilization_); | 336 "lossy_utilization", last_reported_lossy_utilization_); |
| 318 | 337 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 331 media::VideoFrameMetadata::RESOURCE_UTILIZATION, | 350 media::VideoFrameMetadata::RESOURCE_UTILIZATION, |
| 332 encoded_frame->dependency == EncodedFrame::KEY ? | 351 encoded_frame->dependency == EncodedFrame::KEY ? |
| 333 std::min(1.0, attenuated_utilization) : attenuated_utilization); | 352 std::min(1.0, attenuated_utilization) : attenuated_utilization); |
| 334 } | 353 } |
| 335 | 354 |
| 336 SendEncodedFrame(encoder_bitrate, std::move(encoded_frame)); | 355 SendEncodedFrame(encoder_bitrate, std::move(encoded_frame)); |
| 337 } | 356 } |
| 338 | 357 |
| 339 } // namespace cast | 358 } // namespace cast |
| 340 } // namespace media | 359 } // namespace media |
| OLD | NEW |