| 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 |