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

Side by Side Diff: chrome/renderer/media/cast_rtp_stream.cc

Issue 264363005: Cast: deliver video frames on the IO thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: style nits Created 6 years, 7 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 | Annotate | Revision Log
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | content/public/renderer/media_stream_video_sink.h » ('j') | content/public/renderer/media_stream_video_sink.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698