Chromium Code Reviews| 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) { | |
|
perkj_chrome
2014/05/08 08:15:08
FYI- coded_size() is the size from the source befo
Alpha Left Google
2014/05/08 18:45:51
I see. I think this is good for now. We're not app
| |
| 237 error_callback.Run("Video frame resolution does not match config."); | |
| 230 return; | 238 return; |
| 231 } | 239 } |
| 232 | 240 |
| 233 // Capture time is calculated using the time when the first frame | 241 const base::TimeTicks now = base::TimeTicks::Now(); |
| 234 // is delivered. Doing so has less jitter because each frame has | |
| 235 // a TimeDelta from the first frame. However there is a delay between | |
| 236 // capture and delivery here for the first frame. We do not account | |
| 237 // for this delay. | |
| 238 if (first_frame_timestamp_.is_null()) | |
| 239 first_frame_timestamp_ = base::TimeTicks::Now() - frame->timestamp(); | |
| 240 | 242 |
| 241 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc | 243 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc |
| 242 TRACE_EVENT_INSTANT2( | 244 TRACE_EVENT_INSTANT2( |
| 243 "mirroring", "MediaStreamVideoSink::OnVideoFrame", | 245 "cast_perf_test", "MediaStreamVideoSink::OnVideoFrame", |
| 244 TRACE_EVENT_SCOPE_THREAD, | 246 TRACE_EVENT_SCOPE_THREAD, |
| 245 "timestamp", | 247 "timestamp", now.ToInternalValue(), |
| 246 (first_frame_timestamp_ + frame->timestamp()).ToInternalValue(), | |
| 247 "time_delta", frame->timestamp().ToInternalValue()); | 248 "time_delta", frame->timestamp().ToInternalValue()); |
| 248 | 249 frame_input->InsertRawVideoFrame(frame, now); |
| 249 frame_input_->InsertRawVideoFrame( | |
| 250 frame, first_frame_timestamp_ + frame->timestamp()); | |
| 251 } | 250 } |
| 252 | 251 |
| 253 // Attach this sink to a video track represented by |track_|. | 252 // Attach this sink to a video track represented by |track_|. |
| 254 // Data received from the track will be submitted to |frame_input|. | 253 // Data received from the track will be submitted to |frame_input|. |
| 255 void AddToTrack( | 254 void AddToTrack( |
| 256 const scoped_refptr<media::cast::VideoFrameInput>& frame_input) { | 255 const scoped_refptr<media::cast::VideoFrameInput>& frame_input) { |
| 257 DCHECK(!sink_added_); | 256 DCHECK(!sink_added_); |
| 258 sink_added_ = true; | 257 sink_added_ = true; |
| 259 | 258 AddToVideoTrack( |
| 260 frame_input_ = frame_input; | 259 this, |
| 261 AddToVideoTrack(this, track_); | 260 base::Bind( |
| 261 &CastVideoSink::OnVideoFrame, | |
| 262 expected_coded_size_, | |
| 263 error_callback_, | |
| 264 frame_input), | |
| 265 track_); | |
| 262 } | 266 } |
| 263 | 267 |
| 264 private: | 268 private: |
| 265 blink::WebMediaStreamTrack track_; | 269 blink::WebMediaStreamTrack track_; |
| 266 scoped_refptr<media::cast::VideoFrameInput> frame_input_; | |
| 267 bool sink_added_; | 270 bool sink_added_; |
| 268 gfx::Size expected_coded_size_; | 271 gfx::Size expected_coded_size_; |
| 269 CastRtpStream::ErrorCallback error_callback_; | 272 CastRtpStream::ErrorCallback error_callback_; |
| 270 base::TimeTicks first_frame_timestamp_; | |
| 271 | 273 |
| 272 DISALLOW_COPY_AND_ASSIGN(CastVideoSink); | 274 DISALLOW_COPY_AND_ASSIGN(CastVideoSink); |
| 273 }; | 275 }; |
| 274 | 276 |
| 275 // Receives audio data from a MediaStreamTrack. Data is submitted to | 277 // Receives audio data from a MediaStreamTrack. Data is submitted to |
| 276 // media::cast::FrameInput. | 278 // media::cast::FrameInput. |
| 277 // | 279 // |
| 278 // 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. | |
| 279 class CastAudioSink : public base::SupportsWeakPtr<CastAudioSink>, | 283 class CastAudioSink : public base::SupportsWeakPtr<CastAudioSink>, |
| 280 public content::MediaStreamAudioSink { | 284 public content::MediaStreamAudioSink { |
| 281 public: | 285 public: |
| 282 // |track| provides data for this sink. | 286 // |track| provides data for this sink. |
| 283 // |error_callback| is called if audio formats don't match. | 287 // |error_callback| is called if audio formats don't match. |
| 284 CastAudioSink(const blink::WebMediaStreamTrack& track, | 288 CastAudioSink(const blink::WebMediaStreamTrack& track, |
| 285 const CastRtpStream::ErrorCallback& error_callback, | 289 const CastRtpStream::ErrorCallback& error_callback, |
| 286 int output_channels, | 290 int output_channels, |
| 287 int output_sample_rate) | 291 int output_sample_rate) |
| 288 : track_(track), | 292 : track_(track), |
| 289 sink_added_(false), | 293 sink_added_(false), |
| 290 error_callback_(error_callback), | 294 error_callback_(error_callback), |
| 291 weak_factory_(this), | 295 weak_factory_(this), |
| 292 input_preroll_(0), | |
| 293 output_channels_(output_channels), | 296 output_channels_(output_channels), |
| 294 output_sample_rate_(output_sample_rate) {} | 297 output_sample_rate_(output_sample_rate), |
| 298 input_preroll_(0) {} | |
| 295 | 299 |
| 296 virtual ~CastAudioSink() { | 300 virtual ~CastAudioSink() { |
| 297 if (sink_added_) | 301 if (sink_added_) |
| 298 RemoveFromAudioTrack(this, track_); | 302 RemoveFromAudioTrack(this, track_); |
| 299 } | 303 } |
| 300 | 304 |
| 301 // Called on real-time audio thread. | 305 // Called on real-time audio thread. |
| 302 // content::MediaStreamAudioSink implementation. | 306 // content::MediaStreamAudioSink implementation. |
| 303 virtual void OnData(const int16* audio_data, | 307 virtual void OnData(const int16* audio_data, |
| 304 int sample_rate, | 308 int sample_rate, |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 392 void ProvideData(int frame_delay, media::AudioBus* output_bus) { | 396 void ProvideData(int frame_delay, media::AudioBus* output_bus) { |
| 393 fifo_->Consume(output_bus, 0, output_bus->frames()); | 397 fifo_->Consume(output_bus, 0, output_bus->frames()); |
| 394 } | 398 } |
| 395 | 399 |
| 396 private: | 400 private: |
| 397 blink::WebMediaStreamTrack track_; | 401 blink::WebMediaStreamTrack track_; |
| 398 bool sink_added_; | 402 bool sink_added_; |
| 399 CastRtpStream::ErrorCallback error_callback_; | 403 CastRtpStream::ErrorCallback error_callback_; |
| 400 base::WeakPtrFactory<CastAudioSink> weak_factory_; | 404 base::WeakPtrFactory<CastAudioSink> weak_factory_; |
| 401 | 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_; | |
| 402 scoped_ptr<media::MultiChannelResampler> resampler_; | 411 scoped_ptr<media::MultiChannelResampler> resampler_; |
| 403 scoped_ptr<media::AudioFifo> fifo_; | 412 scoped_ptr<media::AudioFifo> fifo_; |
| 404 scoped_ptr<media::AudioBus> fifo_input_bus_; | 413 scoped_ptr<media::AudioBus> fifo_input_bus_; |
| 405 int input_preroll_; | 414 int input_preroll_; |
| 406 const int output_channels_; | |
| 407 const int output_sample_rate_; | |
| 408 | |
| 409 // This member is accessed on the real-time audio time. | |
| 410 scoped_refptr<media::cast::AudioFrameInput> frame_input_; | |
| 411 | 415 |
| 412 DISALLOW_COPY_AND_ASSIGN(CastAudioSink); | 416 DISALLOW_COPY_AND_ASSIGN(CastAudioSink); |
| 413 }; | 417 }; |
| 414 | 418 |
| 415 CastRtpParams::CastRtpParams(const CastRtpPayloadParams& payload_params) | 419 CastRtpParams::CastRtpParams(const CastRtpPayloadParams& payload_params) |
| 416 : payload(payload_params) {} | 420 : payload(payload_params) {} |
| 417 | 421 |
| 418 CastCodecSpecificParams::CastCodecSpecificParams() {} | 422 CastCodecSpecificParams::CastCodecSpecificParams() {} |
| 419 | 423 |
| 420 CastCodecSpecificParams::~CastCodecSpecificParams() {} | 424 CastCodecSpecificParams::~CastCodecSpecificParams() {} |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 528 } | 532 } |
| 529 | 533 |
| 530 void CastRtpStream::DidEncounterError(const std::string& message) { | 534 void CastRtpStream::DidEncounterError(const std::string& message) { |
| 531 // 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. |
| 532 base::WeakPtr<CastRtpStream> ptr = weak_factory_.GetWeakPtr(); | 536 base::WeakPtr<CastRtpStream> ptr = weak_factory_.GetWeakPtr(); |
| 533 error_callback_.Run(message); | 537 error_callback_.Run(message); |
| 534 content::RenderThread::Get()->GetMessageLoop()->PostTask( | 538 content::RenderThread::Get()->GetMessageLoop()->PostTask( |
| 535 FROM_HERE, | 539 FROM_HERE, |
| 536 base::Bind(&CastRtpStream::Stop, ptr)); | 540 base::Bind(&CastRtpStream::Stop, ptr)); |
| 537 } | 541 } |
| OLD | NEW |