OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/video_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/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
14 #include "media/cast/cast_defines.h" | 14 #include "media/cast/cast_defines.h" |
15 #include "media/cast/rtcp/rtcp_defines.h" | 15 #include "media/cast/net/cast_transport_config.h" |
16 #include "media/cast/transport/cast_transport_config.h" | 16 #include "media/cast/net/rtcp/rtcp_defines.h" |
17 #include "media/cast/video_sender/external_video_encoder.h" | 17 #include "media/cast/sender/external_video_encoder.h" |
18 #include "media/cast/video_sender/video_encoder_impl.h" | 18 #include "media/cast/sender/video_encoder_impl.h" |
19 | 19 |
20 namespace media { | 20 namespace media { |
21 namespace cast { | 21 namespace cast { |
22 | 22 |
23 const int kNumAggressiveReportsSentAtStart = 100; | 23 const int kNumAggressiveReportsSentAtStart = 100; |
24 const int kMinSchedulingDelayMs = 1; | 24 const int kMinSchedulingDelayMs = 1; |
25 | 25 |
26 VideoSender::VideoSender( | 26 VideoSender::VideoSender( |
27 scoped_refptr<CastEnvironment> cast_environment, | 27 scoped_refptr<CastEnvironment> cast_environment, |
28 const VideoSenderConfig& video_config, | 28 const VideoSenderConfig& video_config, |
29 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, | 29 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, |
30 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, | 30 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, |
31 transport::CastTransportSender* const transport_sender) | 31 CastTransportSender* const transport_sender) |
32 : cast_environment_(cast_environment), | 32 : cast_environment_(cast_environment), |
33 target_playout_delay_(video_config.target_playout_delay), | 33 target_playout_delay_(video_config.target_playout_delay), |
34 transport_sender_(transport_sender), | 34 transport_sender_(transport_sender), |
35 max_unacked_frames_( | 35 max_unacked_frames_( |
36 std::min(kMaxUnackedFrames, | 36 std::min(kMaxUnackedFrames, |
37 1 + static_cast<int>(target_playout_delay_ * | 37 1 + static_cast<int>(target_playout_delay_ * |
38 video_config.max_frame_rate / | 38 video_config.max_frame_rate / |
39 base::TimeDelta::FromSeconds(1)))), | 39 base::TimeDelta::FromSeconds(1)))), |
40 rtcp_(cast_environment_, | 40 rtcp_(cast_environment_, |
41 this, | 41 this, |
(...skipping 25 matching lines...) Expand all Loading... |
67 video_encoder_.reset(new ExternalVideoEncoder(cast_environment, | 67 video_encoder_.reset(new ExternalVideoEncoder(cast_environment, |
68 video_config, | 68 video_config, |
69 create_vea_cb, | 69 create_vea_cb, |
70 create_video_encode_mem_cb)); | 70 create_video_encode_mem_cb)); |
71 } else { | 71 } else { |
72 video_encoder_.reset(new VideoEncoderImpl( | 72 video_encoder_.reset(new VideoEncoderImpl( |
73 cast_environment, video_config, max_unacked_frames_)); | 73 cast_environment, video_config, max_unacked_frames_)); |
74 } | 74 } |
75 cast_initialization_status_ = STATUS_VIDEO_INITIALIZED; | 75 cast_initialization_status_ = STATUS_VIDEO_INITIALIZED; |
76 | 76 |
77 media::cast::transport::CastTransportRtpConfig transport_config; | 77 media::cast::CastTransportRtpConfig transport_config; |
78 transport_config.ssrc = video_config.ssrc; | 78 transport_config.ssrc = video_config.ssrc; |
79 transport_config.rtp_payload_type = video_config.rtp_payload_type; | 79 transport_config.rtp_payload_type = video_config.rtp_payload_type; |
80 transport_config.stored_frames = max_unacked_frames_; | 80 transport_config.stored_frames = max_unacked_frames_; |
81 transport_config.aes_key = video_config.aes_key; | 81 transport_config.aes_key = video_config.aes_key; |
82 transport_config.aes_iv_mask = video_config.aes_iv_mask; | 82 transport_config.aes_iv_mask = video_config.aes_iv_mask; |
83 transport_sender_->InitializeVideo(transport_config); | 83 transport_sender_->InitializeVideo(transport_config); |
84 | 84 |
85 rtcp_.SetCastReceiverEventHistorySize(kReceiverRtcpEventHistorySize); | 85 rtcp_.SetCastReceiverEventHistorySize(kReceiverRtcpEventHistorySize); |
86 | 86 |
87 memset(frame_id_to_rtp_timestamp_, 0, sizeof(frame_id_to_rtp_timestamp_)); | 87 memset(frame_id_to_rtp_timestamp_, 0, sizeof(frame_id_to_rtp_timestamp_)); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 weak_factory_.GetWeakPtr(), | 134 weak_factory_.GetWeakPtr(), |
135 bitrate))) { | 135 bitrate))) { |
136 frames_in_encoder_++; | 136 frames_in_encoder_++; |
137 } else { | 137 } else { |
138 VLOG(1) << "Encoder rejected a frame. Skipping..."; | 138 VLOG(1) << "Encoder rejected a frame. Skipping..."; |
139 } | 139 } |
140 } | 140 } |
141 | 141 |
142 void VideoSender::SendEncodedVideoFrame( | 142 void VideoSender::SendEncodedVideoFrame( |
143 int requested_bitrate_before_encode, | 143 int requested_bitrate_before_encode, |
144 scoped_ptr<transport::EncodedFrame> encoded_frame) { | 144 scoped_ptr<EncodedFrame> encoded_frame) { |
145 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 145 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
146 | 146 |
147 DCHECK_GT(frames_in_encoder_, 0); | 147 DCHECK_GT(frames_in_encoder_, 0); |
148 frames_in_encoder_--; | 148 frames_in_encoder_--; |
149 | 149 |
150 const uint32 frame_id = encoded_frame->frame_id; | 150 const uint32 frame_id = encoded_frame->frame_id; |
151 | 151 |
152 const bool is_first_frame_to_be_sent = last_send_time_.is_null(); | 152 const bool is_first_frame_to_be_sent = last_send_time_.is_null(); |
153 last_send_time_ = cast_environment_->Clock()->NowTicks(); | 153 last_send_time_ = cast_environment_->Clock()->NowTicks(); |
154 last_sent_frame_id_ = frame_id; | 154 last_sent_frame_id_ = frame_id; |
155 // If this is the first frame about to be sent, fake the value of | 155 // If this is the first frame about to be sent, fake the value of |
156 // |latest_acked_frame_id_| to indicate the receiver starts out all caught up. | 156 // |latest_acked_frame_id_| to indicate the receiver starts out all caught up. |
157 // Also, schedule the periodic frame re-send checks. | 157 // Also, schedule the periodic frame re-send checks. |
158 if (is_first_frame_to_be_sent) { | 158 if (is_first_frame_to_be_sent) { |
159 latest_acked_frame_id_ = frame_id - 1; | 159 latest_acked_frame_id_ = frame_id - 1; |
160 ScheduleNextResendCheck(); | 160 ScheduleNextResendCheck(); |
161 } | 161 } |
162 | 162 |
163 VLOG_IF(1, encoded_frame->dependency == transport::EncodedFrame::KEY) | 163 VLOG_IF(1, encoded_frame->dependency == EncodedFrame::KEY) |
164 << "Send encoded key frame; frame_id: " << frame_id; | 164 << "Send encoded key frame; frame_id: " << frame_id; |
165 | 165 |
166 cast_environment_->Logging()->InsertEncodedFrameEvent( | 166 cast_environment_->Logging()->InsertEncodedFrameEvent( |
167 last_send_time_, FRAME_ENCODED, VIDEO_EVENT, encoded_frame->rtp_timestamp, | 167 last_send_time_, FRAME_ENCODED, VIDEO_EVENT, encoded_frame->rtp_timestamp, |
168 frame_id, static_cast<int>(encoded_frame->data.size()), | 168 frame_id, static_cast<int>(encoded_frame->data.size()), |
169 encoded_frame->dependency == transport::EncodedFrame::KEY, | 169 encoded_frame->dependency == EncodedFrame::KEY, |
170 requested_bitrate_before_encode); | 170 requested_bitrate_before_encode); |
171 // Only use lowest 8 bits as key. | 171 // Only use lowest 8 bits as key. |
172 frame_id_to_rtp_timestamp_[frame_id & 0xff] = encoded_frame->rtp_timestamp; | 172 frame_id_to_rtp_timestamp_[frame_id & 0xff] = encoded_frame->rtp_timestamp; |
173 | 173 |
174 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc | 174 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc |
175 TRACE_EVENT_INSTANT1( | 175 TRACE_EVENT_INSTANT1( |
176 "cast_perf_test", "VideoFrameEncoded", | 176 "cast_perf_test", "VideoFrameEncoded", |
177 TRACE_EVENT_SCOPE_THREAD, | 177 TRACE_EVENT_SCOPE_THREAD, |
178 "rtp_timestamp", encoded_frame->rtp_timestamp); | 178 "rtp_timestamp", encoded_frame->rtp_timestamp); |
179 | 179 |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 rtcp_.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt); | 391 rtcp_.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt); |
392 | 392 |
393 // Sending this extra packet is to kick-start the session. There is | 393 // Sending this extra packet is to kick-start the session. There is |
394 // no need to optimize re-transmission for this case. | 394 // no need to optimize re-transmission for this case. |
395 transport_sender_->ResendPackets(false, missing_frames_and_packets, | 395 transport_sender_->ResendPackets(false, missing_frames_and_packets, |
396 false, rtt); | 396 false, rtt); |
397 } | 397 } |
398 | 398 |
399 } // namespace cast | 399 } // namespace cast |
400 } // namespace media | 400 } // namespace media |
OLD | NEW |