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/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/weak_ptr.h" | 9 #include "base/memory/weak_ptr.h" |
10 #include "chrome/renderer/media/cast_session.h" | 10 #include "chrome/renderer/media/cast_session.h" |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 DCHECK(render_thread_task_runner_->BelongsToCurrentThread()); | 148 DCHECK(render_thread_task_runner_->BelongsToCurrentThread()); |
149 DCHECK(frame_input_); | 149 DCHECK(frame_input_); |
150 // TODO(hclam): Pass in the accurate capture time to have good | 150 // TODO(hclam): Pass in the accurate capture time to have good |
151 // audio/video sync. | 151 // audio/video sync. |
152 frame_input_->InsertRawVideoFrame(frame, base::TimeTicks::Now()); | 152 frame_input_->InsertRawVideoFrame(frame, base::TimeTicks::Now()); |
153 } | 153 } |
154 | 154 |
155 // Attach this sink to MediaStreamTrack. This method call must | 155 // Attach this sink to MediaStreamTrack. This method call must |
156 // be made on the render thread. Incoming data can then be | 156 // be made on the render thread. Incoming data can then be |
157 // passed to media::cast::FrameInput on any thread. | 157 // passed to media::cast::FrameInput on any thread. |
158 void AddToTrack(const scoped_refptr<media::cast::FrameInput>& frame_input) { | 158 void AddToTrack( |
| 159 const scoped_refptr<media::cast::VideoFrameInput>& frame_input) { |
159 DCHECK(render_thread_task_runner_->BelongsToCurrentThread()); | 160 DCHECK(render_thread_task_runner_->BelongsToCurrentThread()); |
160 | 161 |
161 frame_input_ = frame_input; | 162 frame_input_ = frame_input; |
162 if (!sink_added_) { | 163 if (!sink_added_) { |
163 AddToVideoTrack(this, track_); | 164 AddToVideoTrack(this, track_); |
164 sink_added_ = true; | 165 sink_added_ = true; |
165 } | 166 } |
166 } | 167 } |
167 | 168 |
168 private: | 169 private: |
169 blink::WebMediaStreamTrack track_; | 170 blink::WebMediaStreamTrack track_; |
170 scoped_refptr<media::cast::FrameInput> frame_input_; | 171 scoped_refptr<media::cast::VideoFrameInput> frame_input_; |
171 bool sink_added_; | 172 bool sink_added_; |
172 CastRtpStream::ErrorCallback error_callback_; | 173 CastRtpStream::ErrorCallback error_callback_; |
173 scoped_refptr<base::SingleThreadTaskRunner> render_thread_task_runner_; | 174 scoped_refptr<base::SingleThreadTaskRunner> render_thread_task_runner_; |
174 | 175 |
175 DISALLOW_COPY_AND_ASSIGN(CastVideoSink); | 176 DISALLOW_COPY_AND_ASSIGN(CastVideoSink); |
176 }; | 177 }; |
177 | 178 |
178 // Receives audio data from a MediaStreamTrack. Data is submitted to | 179 // Receives audio data from a MediaStreamTrack. Data is submitted to |
179 // media::cast::FrameInput. | 180 // media::cast::FrameInput. |
180 // | 181 // |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 fifo_input_bus_ = media::AudioBus::Create( | 295 fifo_input_bus_ = media::AudioBus::Create( |
295 params.channels(), params.frames_per_buffer()); | 296 params.channels(), params.frames_per_buffer()); |
296 resampler_.reset(new media::MultiChannelResampler( | 297 resampler_.reset(new media::MultiChannelResampler( |
297 output_channels_, | 298 output_channels_, |
298 static_cast<double>(params.sample_rate()) / output_sample_rate_, | 299 static_cast<double>(params.sample_rate()) / output_sample_rate_, |
299 params.frames_per_buffer(), | 300 params.frames_per_buffer(), |
300 base::Bind(&CastAudioSink::ProvideData, base::Unretained(this)))); | 301 base::Bind(&CastAudioSink::ProvideData, base::Unretained(this)))); |
301 } | 302 } |
302 | 303 |
303 // See CastVideoSink for details. | 304 // See CastVideoSink for details. |
304 void AddToTrack(const scoped_refptr<media::cast::FrameInput>& frame_input) { | 305 void AddToTrack( |
| 306 const scoped_refptr<media::cast::AudioFrameInput>& frame_input) { |
305 DCHECK(render_thread_task_runner_->BelongsToCurrentThread()); | 307 DCHECK(render_thread_task_runner_->BelongsToCurrentThread()); |
306 frame_input_ = frame_input; | 308 frame_input_ = frame_input; |
307 if (!sink_added_) { | 309 if (!sink_added_) { |
308 AddToAudioTrack(this, track_); | 310 AddToAudioTrack(this, track_); |
309 sink_added_ = true; | 311 sink_added_ = true; |
310 } | 312 } |
311 } | 313 } |
312 | 314 |
313 void ProvideData(int frame_delay, media::AudioBus* output_bus) { | 315 void ProvideData(int frame_delay, media::AudioBus* output_bus) { |
314 fifo_->Consume(output_bus, 0, output_bus->frames()); | 316 fifo_->Consume(output_bus, 0, output_bus->frames()); |
315 } | 317 } |
316 | 318 |
317 private: | 319 private: |
318 blink::WebMediaStreamTrack track_; | 320 blink::WebMediaStreamTrack track_; |
319 scoped_refptr<media::cast::FrameInput> frame_input_; | 321 scoped_refptr<media::cast::AudioFrameInput> frame_input_; |
320 bool sink_added_; | 322 bool sink_added_; |
321 CastRtpStream::ErrorCallback error_callback_; | 323 CastRtpStream::ErrorCallback error_callback_; |
322 base::WeakPtrFactory<CastAudioSink> weak_factory_; | 324 base::WeakPtrFactory<CastAudioSink> weak_factory_; |
323 scoped_refptr<base::SingleThreadTaskRunner> render_thread_task_runner_; | 325 scoped_refptr<base::SingleThreadTaskRunner> render_thread_task_runner_; |
324 | 326 |
325 scoped_ptr<media::MultiChannelResampler> resampler_; | 327 scoped_ptr<media::MultiChannelResampler> resampler_; |
326 scoped_ptr<media::AudioFifo> fifo_; | 328 scoped_ptr<media::AudioFifo> fifo_; |
327 scoped_ptr<media::AudioBus> fifo_input_bus_; | 329 scoped_ptr<media::AudioBus> fifo_input_bus_; |
328 int input_preroll_; | 330 int input_preroll_; |
329 const int output_channels_; | 331 const int output_channels_; |
(...skipping 11 matching lines...) Expand all Loading... |
341 | 343 |
342 CastRtpPayloadParams::CastRtpPayloadParams() | 344 CastRtpPayloadParams::CastRtpPayloadParams() |
343 : payload_type(0), | 345 : payload_type(0), |
344 ssrc(0), | 346 ssrc(0), |
345 feedback_ssrc(0), | 347 feedback_ssrc(0), |
346 clock_rate(0), | 348 clock_rate(0), |
347 max_bitrate(0), | 349 max_bitrate(0), |
348 min_bitrate(0), | 350 min_bitrate(0), |
349 channels(0), | 351 channels(0), |
350 width(0), | 352 width(0), |
351 height(0) { | 353 height(0) {} |
352 } | |
353 | 354 |
354 CastRtpPayloadParams::~CastRtpPayloadParams() { | 355 CastRtpPayloadParams::~CastRtpPayloadParams() {} |
355 } | |
356 | 356 |
357 CastRtpParams::CastRtpParams() { | 357 CastRtpParams::CastRtpParams() {} |
358 } | |
359 | 358 |
360 CastRtpParams::~CastRtpParams() { | 359 CastRtpParams::~CastRtpParams() {} |
361 } | |
362 | 360 |
363 CastRtpStream::CastRtpStream(const blink::WebMediaStreamTrack& track, | 361 CastRtpStream::CastRtpStream(const blink::WebMediaStreamTrack& track, |
364 const scoped_refptr<CastSession>& session) | 362 const scoped_refptr<CastSession>& session) |
365 : track_(track), | 363 : track_(track), cast_session_(session), weak_factory_(this) {} |
366 cast_session_(session), | |
367 weak_factory_(this) {} | |
368 | 364 |
369 CastRtpStream::~CastRtpStream() { | 365 CastRtpStream::~CastRtpStream() {} |
370 } | |
371 | 366 |
372 std::vector<CastRtpParams> CastRtpStream::GetSupportedParams() { | 367 std::vector<CastRtpParams> CastRtpStream::GetSupportedParams() { |
373 if (IsAudio()) | 368 if (IsAudio()) |
374 return SupportedAudioParams(); | 369 return SupportedAudioParams(); |
375 else | 370 else |
376 return SupportedVideoParams(); | 371 return SupportedVideoParams(); |
377 } | 372 } |
378 | 373 |
379 CastRtpParams CastRtpStream::GetParams() { | 374 CastRtpParams CastRtpStream::GetParams() { return params_; } |
380 return params_; | |
381 } | |
382 | 375 |
383 void CastRtpStream::Start(const CastRtpParams& params, | 376 void CastRtpStream::Start(const CastRtpParams& params, |
384 const base::Closure& start_callback, | 377 const base::Closure& start_callback, |
385 const base::Closure& stop_callback, | 378 const base::Closure& stop_callback, |
386 const ErrorCallback& error_callback) { | 379 const ErrorCallback& error_callback) { |
387 stop_callback_ = stop_callback; | 380 stop_callback_ = stop_callback; |
388 error_callback_ = error_callback; | 381 error_callback_ = error_callback; |
389 | 382 |
390 if (IsAudio()) { | 383 if (IsAudio()) { |
391 AudioSenderConfig config; | 384 AudioSenderConfig config; |
392 if (!ToAudioSenderConfig(params, &config)) { | 385 if (!ToAudioSenderConfig(params, &config)) { |
393 DidEncounterError("Invalid parameters for audio."); | 386 DidEncounterError("Invalid parameters for audio."); |
394 return; | 387 return; |
395 } | 388 } |
396 | 389 |
397 // In case of error we have to go through DidEncounterError() to stop | 390 // In case of error we have to go through DidEncounterError() to stop |
398 // the streaming after reporting the error. | 391 // the streaming after reporting the error. |
399 audio_sink_.reset(new CastAudioSink( | 392 audio_sink_.reset(new CastAudioSink( |
400 track_, | 393 track_, |
401 media::BindToCurrentLoop(base::Bind(&CastRtpStream::DidEncounterError, | 394 media::BindToCurrentLoop(base::Bind(&CastRtpStream::DidEncounterError, |
402 weak_factory_.GetWeakPtr())), | 395 weak_factory_.GetWeakPtr())), |
403 params.payload.channels, | 396 params.payload.channels, |
404 params.payload.clock_rate)); | 397 params.payload.clock_rate)); |
405 cast_session_->StartAudio( | 398 cast_session_->StartAudio( |
406 config, | 399 config, |
407 base::Bind(&CastAudioSink::AddToTrack, | 400 base::Bind(&CastAudioSink::AddToTrack, audio_sink_->AsWeakPtr())); |
408 audio_sink_->AsWeakPtr())); | |
409 start_callback.Run(); | 401 start_callback.Run(); |
410 } else { | 402 } else { |
411 VideoSenderConfig config; | 403 VideoSenderConfig config; |
412 if (!ToVideoSenderConfig(params, &config)) { | 404 if (!ToVideoSenderConfig(params, &config)) { |
413 DidEncounterError("Invalid parameters for video."); | 405 DidEncounterError("Invalid parameters for video."); |
414 return; | 406 return; |
415 } | 407 } |
416 // See the code for audio above for explanation of callbacks. | 408 // See the code for audio above for explanation of callbacks. |
417 video_sink_.reset(new CastVideoSink( | 409 video_sink_.reset(new CastVideoSink( |
418 track_, | 410 track_, |
419 media::BindToCurrentLoop(base::Bind(&CastRtpStream::DidEncounterError, | 411 media::BindToCurrentLoop(base::Bind(&CastRtpStream::DidEncounterError, |
420 weak_factory_.GetWeakPtr())))); | 412 weak_factory_.GetWeakPtr())))); |
421 cast_session_->StartVideo( | 413 cast_session_->StartVideo( |
422 config, | 414 config, |
423 base::Bind(&CastVideoSink::AddToTrack, | 415 base::Bind(&CastVideoSink::AddToTrack, video_sink_->AsWeakPtr())); |
424 video_sink_->AsWeakPtr())); | |
425 start_callback.Run(); | 416 start_callback.Run(); |
426 } | 417 } |
427 } | 418 } |
428 | 419 |
429 void CastRtpStream::Stop() { | 420 void CastRtpStream::Stop() { |
430 audio_sink_.reset(); | 421 audio_sink_.reset(); |
431 video_sink_.reset(); | 422 video_sink_.reset(); |
432 stop_callback_.Run(); | 423 stop_callback_.Run(); |
433 } | 424 } |
434 | 425 |
(...skipping 12 matching lines...) Expand all Loading... |
447 } | 438 } |
448 | 439 |
449 bool CastRtpStream::IsAudio() const { | 440 bool CastRtpStream::IsAudio() const { |
450 return track_.source().type() == blink::WebMediaStreamSource::TypeAudio; | 441 return track_.source().type() == blink::WebMediaStreamSource::TypeAudio; |
451 } | 442 } |
452 | 443 |
453 void CastRtpStream::DidEncounterError(const std::string& message) { | 444 void CastRtpStream::DidEncounterError(const std::string& message) { |
454 error_callback_.Run(message); | 445 error_callback_.Run(message); |
455 Stop(); | 446 Stop(); |
456 } | 447 } |
OLD | NEW |