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