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 "chrome/renderer/media/cast_rtp_stream.h" | 5 #include "chrome/renderer/media/cast_rtp_stream.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/weak_ptr.h" | 10 #include "base/memory/weak_ptr.h" |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 } | 193 } |
194 if (!config->use_external_encoder) { | 194 if (!config->use_external_encoder) { |
195 config->number_of_encode_threads = NumberOfEncodeThreads(); | 195 config->number_of_encode_threads = NumberOfEncodeThreads(); |
196 } | 196 } |
197 return true; | 197 return true; |
198 } | 198 } |
199 | 199 |
200 } // namespace | 200 } // namespace |
201 | 201 |
202 // This class receives MediaStreamTrack events and video frames from a | 202 // This class receives MediaStreamTrack events and video frames from a |
203 // MediaStreamTrack. Video frames are submitted to media::cast::FrameInput. | 203 // MediaStreamTrack. |
204 // | 204 // |
205 // Threading: Video frames are received on the render thread. | 205 // Threading: Video frames are received on the IO thread and then |
| 206 // forwarded to media::cast::VideoFrameInput through a static method. |
| 207 // Member variables of this class are only accessed on the render thread. |
206 class CastVideoSink : public base::SupportsWeakPtr<CastVideoSink>, | 208 class CastVideoSink : public base::SupportsWeakPtr<CastVideoSink>, |
207 public content::MediaStreamVideoSink { | 209 public content::MediaStreamVideoSink { |
208 public: | 210 public: |
209 // |track| provides data for this sink. | 211 // |track| provides data for this sink. |
210 // |expected_coded_size| is the expected dimension of the video frame. | 212 // |expected_coded_size| is the expected dimension of the video frame. |
211 // |error_callback| is called if video formats don't match. | 213 // |error_callback| is called if video formats don't match. |
212 CastVideoSink(const blink::WebMediaStreamTrack& track, | 214 CastVideoSink(const blink::WebMediaStreamTrack& track, |
213 const gfx::Size& expected_coded_size, | 215 const gfx::Size& expected_coded_size, |
214 const CastRtpStream::ErrorCallback& error_callback) | 216 const CastRtpStream::ErrorCallback& error_callback) |
215 : track_(track), | 217 : track_(track), |
216 sink_added_(false), | 218 sink_added_(false), |
217 expected_coded_size_(expected_coded_size), | 219 expected_coded_size_(expected_coded_size), |
218 error_callback_(error_callback) {} | 220 error_callback_(error_callback) {} |
219 | 221 |
220 virtual ~CastVideoSink() { | 222 virtual ~CastVideoSink() { |
221 if (sink_added_) | 223 if (sink_added_) |
222 RemoveFromVideoTrack(this, track_); | 224 RemoveFromVideoTrack(this, track_); |
223 } | 225 } |
224 | 226 |
225 // content::MediaStreamVideoSink implementation. | 227 // This static method is used to forward video frames to |frame_input|. |
226 virtual void OnVideoFrame(const scoped_refptr<media::VideoFrame>& frame) | 228 static void OnVideoFrame( |
227 OVERRIDE { | 229 // These parameters are already bound when callback is created. |
228 if (frame->coded_size() != expected_coded_size_) { | 230 const gfx::Size& expected_coded_size, |
229 error_callback_.Run("Video frame resolution does not match config."); | 231 const CastRtpStream::ErrorCallback& error_callback, |
| 232 const scoped_refptr<media::cast::VideoFrameInput> frame_input, |
| 233 // These parameters are passed for each frame. |
| 234 const scoped_refptr<media::VideoFrame>& frame, |
| 235 const media::VideoCaptureFormat& format) { |
| 236 if (frame->coded_size() != expected_coded_size) { |
| 237 error_callback.Run("Video frame resolution does not match config."); |
230 return; | 238 return; |
231 } | 239 } |
232 | 240 |
233 const base::TimeTicks now = base::TimeTicks::Now(); | 241 const base::TimeTicks now = base::TimeTicks::Now(); |
234 | 242 |
235 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc | 243 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc |
236 TRACE_EVENT_INSTANT2( | 244 TRACE_EVENT_INSTANT2( |
237 "mirroring", "MediaStreamVideoSink::OnVideoFrame", | 245 "cast_perf_test", "MediaStreamVideoSink::OnVideoFrame", |
238 TRACE_EVENT_SCOPE_THREAD, | 246 TRACE_EVENT_SCOPE_THREAD, |
239 "timestamp", now.ToInternalValue(), | 247 "timestamp", now.ToInternalValue(), |
240 "time_delta", frame->timestamp().ToInternalValue()); | 248 "time_delta", frame->timestamp().ToInternalValue()); |
241 frame_input_->InsertRawVideoFrame(frame, now); | 249 frame_input->InsertRawVideoFrame(frame, now); |
242 } | 250 } |
243 | 251 |
244 // Attach this sink to a video track represented by |track_|. | 252 // Attach this sink to a video track represented by |track_|. |
245 // Data received from the track will be submitted to |frame_input|. | 253 // Data received from the track will be submitted to |frame_input|. |
246 void AddToTrack( | 254 void AddToTrack( |
247 const scoped_refptr<media::cast::VideoFrameInput>& frame_input) { | 255 const scoped_refptr<media::cast::VideoFrameInput>& frame_input) { |
248 DCHECK(!sink_added_); | 256 DCHECK(!sink_added_); |
249 sink_added_ = true; | 257 sink_added_ = true; |
250 | 258 AddToVideoTrack( |
251 frame_input_ = frame_input; | 259 this, |
252 AddToVideoTrack(this, track_); | 260 base::Bind( |
| 261 &CastVideoSink::OnVideoFrame, |
| 262 expected_coded_size_, |
| 263 error_callback_, |
| 264 frame_input), |
| 265 track_); |
253 } | 266 } |
254 | 267 |
255 private: | 268 private: |
256 blink::WebMediaStreamTrack track_; | 269 blink::WebMediaStreamTrack track_; |
257 scoped_refptr<media::cast::VideoFrameInput> frame_input_; | |
258 bool sink_added_; | 270 bool sink_added_; |
259 gfx::Size expected_coded_size_; | 271 gfx::Size expected_coded_size_; |
260 CastRtpStream::ErrorCallback error_callback_; | 272 CastRtpStream::ErrorCallback error_callback_; |
261 | 273 |
262 DISALLOW_COPY_AND_ASSIGN(CastVideoSink); | 274 DISALLOW_COPY_AND_ASSIGN(CastVideoSink); |
263 }; | 275 }; |
264 | 276 |
265 // Receives audio data from a MediaStreamTrack. Data is submitted to | 277 // Receives audio data from a MediaStreamTrack. Data is submitted to |
266 // media::cast::FrameInput. | 278 // media::cast::FrameInput. |
267 // | 279 // |
268 // Threading: Audio frames are received on the real-time audio thread. | 280 // Threading: Audio frames are received on the real-time audio thread. |
| 281 // Note that RemoveFromAudioTrack() is synchronous and we have |
| 282 // gurantee that there will be no more audio data after calling it. |
269 class CastAudioSink : public base::SupportsWeakPtr<CastAudioSink>, | 283 class CastAudioSink : public base::SupportsWeakPtr<CastAudioSink>, |
270 public content::MediaStreamAudioSink { | 284 public content::MediaStreamAudioSink { |
271 public: | 285 public: |
272 // |track| provides data for this sink. | 286 // |track| provides data for this sink. |
273 // |error_callback| is called if audio formats don't match. | 287 // |error_callback| is called if audio formats don't match. |
274 CastAudioSink(const blink::WebMediaStreamTrack& track, | 288 CastAudioSink(const blink::WebMediaStreamTrack& track, |
275 const CastRtpStream::ErrorCallback& error_callback, | 289 const CastRtpStream::ErrorCallback& error_callback, |
276 int output_channels, | 290 int output_channels, |
277 int output_sample_rate) | 291 int output_sample_rate) |
278 : track_(track), | 292 : track_(track), |
279 sink_added_(false), | 293 sink_added_(false), |
280 error_callback_(error_callback), | 294 error_callback_(error_callback), |
281 weak_factory_(this), | 295 weak_factory_(this), |
282 input_preroll_(0), | |
283 output_channels_(output_channels), | 296 output_channels_(output_channels), |
284 output_sample_rate_(output_sample_rate) {} | 297 output_sample_rate_(output_sample_rate), |
| 298 input_preroll_(0) {} |
285 | 299 |
286 virtual ~CastAudioSink() { | 300 virtual ~CastAudioSink() { |
287 if (sink_added_) | 301 if (sink_added_) |
288 RemoveFromAudioTrack(this, track_); | 302 RemoveFromAudioTrack(this, track_); |
289 } | 303 } |
290 | 304 |
291 // Called on real-time audio thread. | 305 // Called on real-time audio thread. |
292 // content::MediaStreamAudioSink implementation. | 306 // content::MediaStreamAudioSink implementation. |
293 virtual void OnData(const int16* audio_data, | 307 virtual void OnData(const int16* audio_data, |
294 int sample_rate, | 308 int sample_rate, |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 void ProvideData(int frame_delay, media::AudioBus* output_bus) { | 396 void ProvideData(int frame_delay, media::AudioBus* output_bus) { |
383 fifo_->Consume(output_bus, 0, output_bus->frames()); | 397 fifo_->Consume(output_bus, 0, output_bus->frames()); |
384 } | 398 } |
385 | 399 |
386 private: | 400 private: |
387 blink::WebMediaStreamTrack track_; | 401 blink::WebMediaStreamTrack track_; |
388 bool sink_added_; | 402 bool sink_added_; |
389 CastRtpStream::ErrorCallback error_callback_; | 403 CastRtpStream::ErrorCallback error_callback_; |
390 base::WeakPtrFactory<CastAudioSink> weak_factory_; | 404 base::WeakPtrFactory<CastAudioSink> weak_factory_; |
391 | 405 |
| 406 const int output_channels_; |
| 407 const int output_sample_rate_; |
| 408 |
| 409 // These member are accessed on the real-time audio time only. |
| 410 scoped_refptr<media::cast::AudioFrameInput> frame_input_; |
392 scoped_ptr<media::MultiChannelResampler> resampler_; | 411 scoped_ptr<media::MultiChannelResampler> resampler_; |
393 scoped_ptr<media::AudioFifo> fifo_; | 412 scoped_ptr<media::AudioFifo> fifo_; |
394 scoped_ptr<media::AudioBus> fifo_input_bus_; | 413 scoped_ptr<media::AudioBus> fifo_input_bus_; |
395 int input_preroll_; | 414 int input_preroll_; |
396 const int output_channels_; | |
397 const int output_sample_rate_; | |
398 | |
399 // This member is accessed on the real-time audio time. | |
400 scoped_refptr<media::cast::AudioFrameInput> frame_input_; | |
401 | 415 |
402 DISALLOW_COPY_AND_ASSIGN(CastAudioSink); | 416 DISALLOW_COPY_AND_ASSIGN(CastAudioSink); |
403 }; | 417 }; |
404 | 418 |
405 CastRtpParams::CastRtpParams(const CastRtpPayloadParams& payload_params) | 419 CastRtpParams::CastRtpParams(const CastRtpPayloadParams& payload_params) |
406 : payload(payload_params) {} | 420 : payload(payload_params) {} |
407 | 421 |
408 CastCodecSpecificParams::CastCodecSpecificParams() {} | 422 CastCodecSpecificParams::CastCodecSpecificParams() {} |
409 | 423 |
410 CastCodecSpecificParams::~CastCodecSpecificParams() {} | 424 CastCodecSpecificParams::~CastCodecSpecificParams() {} |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 } | 532 } |
519 | 533 |
520 void CastRtpStream::DidEncounterError(const std::string& message) { | 534 void CastRtpStream::DidEncounterError(const std::string& message) { |
521 // Save the WeakPtr first because the error callback might delete this object. | 535 // Save the WeakPtr first because the error callback might delete this object. |
522 base::WeakPtr<CastRtpStream> ptr = weak_factory_.GetWeakPtr(); | 536 base::WeakPtr<CastRtpStream> ptr = weak_factory_.GetWeakPtr(); |
523 error_callback_.Run(message); | 537 error_callback_.Run(message); |
524 content::RenderThread::Get()->GetMessageLoop()->PostTask( | 538 content::RenderThread::Get()->GetMessageLoop()->PostTask( |
525 FROM_HERE, | 539 FROM_HERE, |
526 base::Bind(&CastRtpStream::Stop, ptr)); | 540 base::Bind(&CastRtpStream::Stop, ptr)); |
527 } | 541 } |
OLD | NEW |