Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: media/cast/sender/video_sender.cc

Issue 901833004: [Cast] Repurpose CastInitializationStatus for variable frame size support. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Compile fixes. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/message_loop/message_loop.h"
13 #include "base/trace_event/trace_event.h" 12 #include "base/trace_event/trace_event.h"
14 #include "media/cast/cast_defines.h" 13 #include "media/cast/cast_defines.h"
15 #include "media/cast/net/cast_transport_config.h" 14 #include "media/cast/net/cast_transport_config.h"
16 #include "media/cast/sender/external_video_encoder.h" 15 #include "media/cast/sender/external_video_encoder.h"
17 #include "media/cast/sender/video_encoder_impl.h" 16 #include "media/cast/sender/video_encoder_impl.h"
18 #include "media/cast/sender/video_frame_factory.h" 17 #include "media/cast/sender/video_frame_factory.h"
19 18
20 #if defined(OS_MACOSX) 19 #if defined(OS_MACOSX)
21 #include "media/cast/sender/h264_vt_encoder.h" 20 #include "media/cast/sender/h264_vt_encoder.h"
22 #endif 21 #endif
(...skipping 16 matching lines...) Expand all
39 38
40 } // namespace 39 } // namespace
41 40
42 // Note, we use a fixed bitrate value when external video encoder is used. 41 // Note, we use a fixed bitrate value when external video encoder is used.
43 // Some hardware encoder shows bad behavior if we set the bitrate too 42 // Some hardware encoder shows bad behavior if we set the bitrate too
44 // frequently, e.g. quality drop, not abiding by target bitrate, etc. 43 // frequently, e.g. quality drop, not abiding by target bitrate, etc.
45 // See details: crbug.com/392086. 44 // See details: crbug.com/392086.
46 VideoSender::VideoSender( 45 VideoSender::VideoSender(
47 scoped_refptr<CastEnvironment> cast_environment, 46 scoped_refptr<CastEnvironment> cast_environment,
48 const VideoSenderConfig& video_config, 47 const VideoSenderConfig& video_config,
49 const CastInitializationCallback& initialization_cb, 48 const StatusChangeCallback& status_change_cb,
50 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, 49 const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
51 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, 50 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
52 CastTransportSender* const transport_sender, 51 CastTransportSender* const transport_sender,
53 const PlayoutDelayChangeCB& playout_delay_change_cb) 52 const PlayoutDelayChangeCB& playout_delay_change_cb)
54 : FrameSender( 53 : FrameSender(
55 cast_environment, 54 cast_environment,
56 false, 55 false,
57 transport_sender, 56 transport_sender,
58 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval), 57 base::TimeDelta::FromMilliseconds(video_config.rtcp_interval),
59 kVideoFrequency, 58 kVideoFrequency,
60 video_config.ssrc, 59 video_config.ssrc,
61 video_config.max_frame_rate, 60 video_config.max_frame_rate,
62 video_config.min_playout_delay, 61 video_config.min_playout_delay,
63 video_config.max_playout_delay, 62 video_config.max_playout_delay,
64 video_config.use_external_encoder ? 63 video_config.use_external_encoder ?
65 NewFixedCongestionControl( 64 NewFixedCongestionControl(
66 (video_config.min_bitrate + video_config.max_bitrate) / 2) : 65 (video_config.min_bitrate + video_config.max_bitrate) / 2) :
67 NewAdaptiveCongestionControl(cast_environment->Clock(), 66 NewAdaptiveCongestionControl(cast_environment->Clock(),
68 video_config.max_bitrate, 67 video_config.max_bitrate,
69 video_config.min_bitrate, 68 video_config.min_bitrate,
70 video_config.max_frame_rate)), 69 video_config.max_frame_rate)),
71 frames_in_encoder_(0), 70 frames_in_encoder_(0),
72 last_bitrate_(0), 71 last_bitrate_(0),
73 playout_delay_change_cb_(playout_delay_change_cb), 72 playout_delay_change_cb_(playout_delay_change_cb),
74 weak_factory_(this) { 73 weak_factory_(this) {
75 cast_initialization_status_ = STATUS_VIDEO_UNINITIALIZED;
76
77 #if defined(OS_MACOSX) 74 #if defined(OS_MACOSX)
78 // On Apple platforms, use the hardware H.264 encoder if possible. It is the 75 // On Apple platforms, use the hardware H.264 encoder if possible. It is the
79 // only reasonable option for iOS. 76 // only reasonable option for iOS.
80 if (!video_config.use_external_encoder && 77 if (!video_config.use_external_encoder &&
81 video_config.codec == CODEC_VIDEO_H264) { 78 video_config.codec == CODEC_VIDEO_H264) {
82 video_encoder_.reset(new H264VideoToolboxEncoder( 79 video_encoder_.reset(new H264VideoToolboxEncoder(
83 cast_environment, 80 cast_environment,
84 video_config, 81 video_config,
85 gfx::Size(video_config.width, video_config.height), 82 gfx::Size(video_config.width, video_config.height),
86 base::Bind(&VideoSender::OnEncoderInitialized, 83 status_change_cb));
87 weak_factory_.GetWeakPtr(),
88 initialization_cb)));
89 } 84 }
90 #endif // defined(OS_MACOSX) 85 #endif // defined(OS_MACOSX)
91 #if !defined(OS_IOS) 86 #if !defined(OS_IOS)
92 if (video_config.use_external_encoder) { 87 if (video_config.use_external_encoder) {
93 video_encoder_.reset(new ExternalVideoEncoder( 88 video_encoder_.reset(new ExternalVideoEncoder(
94 cast_environment, 89 cast_environment,
95 video_config, 90 video_config,
96 gfx::Size(video_config.width, video_config.height), 91 gfx::Size(video_config.width, video_config.height),
97 base::Bind(&VideoSender::OnEncoderInitialized, 92 status_change_cb,
98 weak_factory_.GetWeakPtr(), initialization_cb),
99 create_vea_cb, 93 create_vea_cb,
100 create_video_encode_mem_cb)); 94 create_video_encode_mem_cb));
101 } else if (!video_encoder_) { 95 } else if (!video_encoder_) {
102 // Software encoder is initialized immediately. 96 // Software encoder is initialized immediately.
103 video_encoder_.reset(new VideoEncoderImpl( 97 video_encoder_.reset(new VideoEncoderImpl(
104 cast_environment, video_config, initialization_cb)); 98 cast_environment, video_config, status_change_cb));
105 cast_initialization_status_ = STATUS_VIDEO_INITIALIZED;
106 } 99 }
107 #endif // !defined(OS_IOS) 100 #endif // !defined(OS_IOS)
108 101
102 if (!video_encoder_) {
103 cast_environment_->PostTask(
104 CastEnvironment::MAIN,
105 FROM_HERE,
106 base::Bind(status_change_cb, STATUS_UNSUPPORTED_CODEC));
107 }
108
109 media::cast::CastTransportRtpConfig transport_config; 109 media::cast::CastTransportRtpConfig transport_config;
110 transport_config.ssrc = video_config.ssrc; 110 transport_config.ssrc = video_config.ssrc;
111 transport_config.feedback_ssrc = video_config.receiver_ssrc; 111 transport_config.feedback_ssrc = video_config.receiver_ssrc;
112 transport_config.rtp_payload_type = video_config.rtp_payload_type; 112 transport_config.rtp_payload_type = video_config.rtp_payload_type;
113 transport_config.aes_key = video_config.aes_key; 113 transport_config.aes_key = video_config.aes_key;
114 transport_config.aes_iv_mask = video_config.aes_iv_mask; 114 transport_config.aes_iv_mask = video_config.aes_iv_mask;
115 115
116 transport_sender->InitializeVideo( 116 transport_sender->InitializeVideo(
117 transport_config, 117 transport_config,
118 base::Bind(&VideoSender::OnReceivedCastFeedback, 118 base::Bind(&VideoSender::OnReceivedCastFeedback,
119 weak_factory_.GetWeakPtr()), 119 weak_factory_.GetWeakPtr()),
120 base::Bind(&VideoSender::OnMeasuredRoundTripTime, 120 base::Bind(&VideoSender::OnMeasuredRoundTripTime,
121 weak_factory_.GetWeakPtr())); 121 weak_factory_.GetWeakPtr()));
122 } 122 }
123 123
124 VideoSender::~VideoSender() { 124 VideoSender::~VideoSender() {
125 } 125 }
126 126
127 void VideoSender::InsertRawVideoFrame( 127 void VideoSender::InsertRawVideoFrame(
128 const scoped_refptr<media::VideoFrame>& video_frame, 128 const scoped_refptr<media::VideoFrame>& video_frame,
129 const base::TimeTicks& reference_time) { 129 const base::TimeTicks& reference_time) {
130 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 130 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
131 if (cast_initialization_status_ != STATUS_VIDEO_INITIALIZED) { 131
132 if (!video_encoder_) {
132 NOTREACHED(); 133 NOTREACHED();
133 return; 134 return;
134 } 135 }
135 DCHECK(video_encoder_.get()) << "Invalid state";
136 136
137 const RtpTimestamp rtp_timestamp = 137 const RtpTimestamp rtp_timestamp =
138 TimeDeltaToRtpDelta(video_frame->timestamp(), kVideoFrequency); 138 TimeDeltaToRtpDelta(video_frame->timestamp(), kVideoFrequency);
139 const base::TimeTicks insertion_time = cast_environment_->Clock()->NowTicks(); 139 const base::TimeTicks insertion_time = cast_environment_->Clock()->NowTicks();
140 // TODO(miu): Plumb in capture timestamps. For now, make it look like capture 140 // TODO(miu): Plumb in capture timestamps. For now, make it look like capture
141 // took zero time by setting the BEGIN and END event to the same timestamp. 141 // took zero time by setting the BEGIN and END event to the same timestamp.
142 cast_environment_->Logging()->InsertFrameEvent( 142 cast_environment_->Logging()->InsertFrameEvent(
143 insertion_time, FRAME_CAPTURE_BEGIN, VIDEO_EVENT, rtp_timestamp, 143 insertion_time, FRAME_CAPTURE_BEGIN, VIDEO_EVENT, rtp_timestamp,
144 kFrameIdUnknown); 144 kFrameIdUnknown);
145 cast_environment_->Logging()->InsertFrameEvent( 145 cast_environment_->Logging()->InsertFrameEvent(
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 frames_in_encoder_++; 211 frames_in_encoder_++;
212 duration_in_encoder_ += duration_added_by_next_frame; 212 duration_in_encoder_ += duration_added_by_next_frame;
213 last_enqueued_frame_rtp_timestamp_ = rtp_timestamp; 213 last_enqueued_frame_rtp_timestamp_ = rtp_timestamp;
214 last_enqueued_frame_reference_time_ = reference_time; 214 last_enqueued_frame_reference_time_ = reference_time;
215 } else { 215 } else {
216 VLOG(1) << "Encoder rejected a frame. Skipping..."; 216 VLOG(1) << "Encoder rejected a frame. Skipping...";
217 } 217 }
218 } 218 }
219 219
220 scoped_ptr<VideoFrameFactory> VideoSender::CreateVideoFrameFactory() { 220 scoped_ptr<VideoFrameFactory> VideoSender::CreateVideoFrameFactory() {
221 DCHECK(cast_initialization_status_ == STATUS_VIDEO_INITIALIZED); 221 return video_encoder_ ? video_encoder_->CreateVideoFrameFactory() : nullptr;
222 DCHECK(video_encoder_.get()) << "Invalid state";
223 return video_encoder_->CreateVideoFrameFactory();
224 } 222 }
225 223
226 int VideoSender::GetNumberOfFramesInEncoder() const { 224 int VideoSender::GetNumberOfFramesInEncoder() const {
227 return frames_in_encoder_; 225 return frames_in_encoder_;
228 } 226 }
229 227
230 base::TimeDelta VideoSender::GetInFlightMediaDuration() const { 228 base::TimeDelta VideoSender::GetInFlightMediaDuration() const {
231 if (GetUnacknowledgedFrameCount() > 0) { 229 if (GetUnacknowledgedFrameCount() > 0) {
232 const uint32 oldest_unacked_frame_id = latest_acked_frame_id_ + 1; 230 const uint32 oldest_unacked_frame_id = latest_acked_frame_id_ + 1;
233 return last_enqueued_frame_reference_time_ - 231 return last_enqueued_frame_reference_time_ -
234 GetRecordedReferenceTime(oldest_unacked_frame_id); 232 GetRecordedReferenceTime(oldest_unacked_frame_id);
235 } else { 233 } else {
236 return duration_in_encoder_; 234 return duration_in_encoder_;
237 } 235 }
238 } 236 }
239 237
240 void VideoSender::OnAck(uint32 frame_id) { 238 void VideoSender::OnAck(uint32 frame_id) {
241 video_encoder_->LatestFrameIdToReference(frame_id); 239 video_encoder_->LatestFrameIdToReference(frame_id);
242 } 240 }
243 241
244 void VideoSender::OnEncoderInitialized(
245 const CastInitializationCallback& initialization_cb,
246 CastInitializationStatus status) {
247 cast_initialization_status_ = status;
248 initialization_cb.Run(status);
249 }
250
251 void VideoSender::OnEncodedVideoFrame( 242 void VideoSender::OnEncodedVideoFrame(
252 int encoder_bitrate, 243 int encoder_bitrate,
253 scoped_ptr<EncodedFrame> encoded_frame) { 244 scoped_ptr<EncodedFrame> encoded_frame) {
254 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 245 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
255 246
256 frames_in_encoder_--; 247 frames_in_encoder_--;
257 DCHECK_GE(frames_in_encoder_, 0); 248 DCHECK_GE(frames_in_encoder_, 0);
258 249
259 duration_in_encoder_ = 250 duration_in_encoder_ =
260 last_enqueued_frame_reference_time_ - encoded_frame->reference_time; 251 last_enqueued_frame_reference_time_ - encoded_frame->reference_time;
261 252
262 SendEncodedFrame(encoder_bitrate, encoded_frame.Pass()); 253 SendEncodedFrame(encoder_bitrate, encoded_frame.Pass());
263 } 254 }
264 255
265 } // namespace cast 256 } // namespace cast
266 } // namespace media 257 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698