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

Side by Side Diff: content/renderer/media/webrtc_audio_renderer.cc

Issue 2517503003: Reland: Make more media APIs aware of |delay| and |delay_timestamp| (Closed)
Patch Set: Comments from chcunningham@ and Dale Created 4 years 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
« no previous file with comments | « content/renderer/media/webrtc_audio_renderer.h ('k') | media/audio/audio_output_controller.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/renderer/media/webrtc_audio_renderer.h" 5 #include "content/renderer/media/webrtc_audio_renderer.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 const std::string& device_id, 160 const std::string& device_id,
161 const url::Origin& security_origin) 161 const url::Origin& security_origin)
162 : state_(UNINITIALIZED), 162 : state_(UNINITIALIZED),
163 source_render_frame_id_(source_render_frame_id), 163 source_render_frame_id_(source_render_frame_id),
164 session_id_(session_id), 164 session_id_(session_id),
165 signaling_thread_(signaling_thread), 165 signaling_thread_(signaling_thread),
166 media_stream_(media_stream), 166 media_stream_(media_stream),
167 source_(NULL), 167 source_(NULL),
168 play_ref_count_(0), 168 play_ref_count_(0),
169 start_ref_count_(0), 169 start_ref_count_(0),
170 audio_delay_milliseconds_(0),
171 sink_params_(kFormat, kChannelLayout, 0, kBitsPerSample, 0), 170 sink_params_(kFormat, kChannelLayout, 0, kBitsPerSample, 0),
172 output_device_id_(device_id), 171 output_device_id_(device_id),
173 security_origin_(security_origin) { 172 security_origin_(security_origin) {
174 WebRtcLogMessage(base::StringPrintf( 173 WebRtcLogMessage(base::StringPrintf(
175 "WAR::WAR. source_render_frame_id=%d, session_id=%d, effects=%i", 174 "WAR::WAR. source_render_frame_id=%d, session_id=%d, effects=%i",
176 source_render_frame_id, session_id, sink_params_.effects())); 175 source_render_frame_id, session_id, sink_params_.effects()));
177 } 176 }
178 177
179 WebRtcAudioRenderer::~WebRtcAudioRenderer() { 178 WebRtcAudioRenderer::~WebRtcAudioRenderer() {
180 DCHECK(thread_checker_.CalledOnValidThread()); 179 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 if (state_ == UNINITIALIZED) 260 if (state_ == UNINITIALIZED)
262 return; 261 return;
263 262
264 DCHECK(play_ref_count_ == 0 || state_ == PLAYING); 263 DCHECK(play_ref_count_ == 0 || state_ == PLAYING);
265 ++play_ref_count_; 264 ++play_ref_count_;
266 265
267 if (state_ != PLAYING) { 266 if (state_ != PLAYING) {
268 state_ = PLAYING; 267 state_ = PLAYING;
269 268
270 if (audio_fifo_) { 269 if (audio_fifo_) {
271 audio_delay_milliseconds_ = 0; 270 audio_delay_ = base::TimeDelta();
272 audio_fifo_->Clear(); 271 audio_fifo_->Clear();
273 } 272 }
274 } 273 }
275 } 274 }
276 275
277 void WebRtcAudioRenderer::Pause() { 276 void WebRtcAudioRenderer::Pause() {
278 DVLOG(1) << "WebRtcAudioRenderer::Pause()"; 277 DVLOG(1) << "WebRtcAudioRenderer::Pause()";
279 DCHECK(thread_checker_.CalledOnValidThread()); 278 DCHECK(thread_checker_.CalledOnValidThread());
280 if (!playing_state_.playing()) 279 if (!playing_state_.playing())
281 return; 280 return;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 base::AutoLock auto_lock(lock_); 393 base::AutoLock auto_lock(lock_);
395 source_->AudioRendererThreadStopped(); 394 source_->AudioRendererThreadStopped();
396 } 395 }
397 PrepareSink(); 396 PrepareSink();
398 sink_->Start(); 397 sink_->Start();
399 sink_->Play(); // Not all the sinks play on start. 398 sink_->Play(); // Not all the sinks play on start.
400 399
401 callback.Run(media::OUTPUT_DEVICE_STATUS_OK); 400 callback.Run(media::OUTPUT_DEVICE_STATUS_OK);
402 } 401 }
403 402
404 int WebRtcAudioRenderer::Render(media::AudioBus* audio_bus, 403 int WebRtcAudioRenderer::Render(base::TimeDelta delay,
405 uint32_t frames_delayed, 404 base::TimeTicks delay_timestamp,
406 uint32_t frames_skipped) { 405 int prior_frames_skipped,
406 media::AudioBus* audio_bus) {
407 DCHECK(sink_->CurrentThreadIsRenderingThread()); 407 DCHECK(sink_->CurrentThreadIsRenderingThread());
408 base::AutoLock auto_lock(lock_); 408 base::AutoLock auto_lock(lock_);
409 if (!source_) 409 if (!source_)
410 return 0; 410 return 0;
411 411
412 // TODO(grunell): Converting from frames to milliseconds will potentially lose 412 DVLOG(2) << "WebRtcAudioRenderer::Render()";
413 // hundreds of microseconds which may cause audio video drift. Update 413 DVLOG(2) << "audio_delay: " << delay;
414 // this class and all usage of render delay msec -> frames (possibly even
415 // using a double type for frames). See http://crbug.com/586540
416 uint32_t audio_delay_milliseconds = static_cast<double>(frames_delayed) *
417 base::Time::kMillisecondsPerSecond /
418 sink_params_.sample_rate();
419 414
420 DVLOG(2) << "WebRtcAudioRenderer::Render()"; 415 audio_delay_ = delay;
421 DVLOG(2) << "audio_delay_milliseconds: " << audio_delay_milliseconds;
422
423 DCHECK_LE(audio_delay_milliseconds, static_cast<uint32_t>(INT_MAX));
424 audio_delay_milliseconds_ = static_cast<int>(audio_delay_milliseconds);
425 416
426 // If there are skipped frames, pull and throw away the same amount. We always 417 // If there are skipped frames, pull and throw away the same amount. We always
427 // pull 10 ms of data from the source (see PrepareSink()), so the fifo is only 418 // pull 10 ms of data from the source (see PrepareSink()), so the fifo is only
428 // required if the number of frames to drop doesn't correspond to 10 ms. 419 // required if the number of frames to drop doesn't correspond to 10 ms.
429 if (frames_skipped > 0) { 420 if (prior_frames_skipped > 0) {
430 const uint32_t source_frames_per_buffer = 421 const int source_frames_per_buffer = sink_params_.sample_rate() / 100;
431 static_cast<uint32_t>(sink_params_.sample_rate() / 100); 422 if (!audio_fifo_ && prior_frames_skipped != source_frames_per_buffer) {
432 if (!audio_fifo_ && frames_skipped != source_frames_per_buffer) {
433 audio_fifo_.reset(new media::AudioPullFifo( 423 audio_fifo_.reset(new media::AudioPullFifo(
434 kChannels, source_frames_per_buffer, 424 kChannels, source_frames_per_buffer,
435 base::Bind(&WebRtcAudioRenderer::SourceCallback, 425 base::Bind(&WebRtcAudioRenderer::SourceCallback,
436 base::Unretained(this)))); 426 base::Unretained(this))));
437 } 427 }
438 428
439 std::unique_ptr<media::AudioBus> drop_bus = 429 std::unique_ptr<media::AudioBus> drop_bus =
440 media::AudioBus::Create(audio_bus->channels(), frames_skipped); 430 media::AudioBus::Create(audio_bus->channels(), prior_frames_skipped);
441 if (audio_fifo_) 431 if (audio_fifo_)
442 audio_fifo_->Consume(drop_bus.get(), drop_bus->frames()); 432 audio_fifo_->Consume(drop_bus.get(), drop_bus->frames());
443 else 433 else
444 SourceCallback(0, drop_bus.get()); 434 SourceCallback(0, drop_bus.get());
445 } 435 }
446 436
447 // Pull the data we will deliver. 437 // Pull the data we will deliver.
448 if (audio_fifo_) 438 if (audio_fifo_)
449 audio_fifo_->Consume(audio_bus, audio_bus->frames()); 439 audio_fifo_->Consume(audio_bus, audio_bus->frames());
450 else 440 else
451 SourceCallback(0, audio_bus); 441 SourceCallback(0, audio_bus);
452 442
453 return (state_ == PLAYING) ? audio_bus->frames() : 0; 443 return (state_ == PLAYING) ? audio_bus->frames() : 0;
454 } 444 }
455 445
456 void WebRtcAudioRenderer::OnRenderError() { 446 void WebRtcAudioRenderer::OnRenderError() {
457 NOTIMPLEMENTED(); 447 NOTIMPLEMENTED();
458 LOG(ERROR) << "OnRenderError()"; 448 LOG(ERROR) << "OnRenderError()";
459 } 449 }
460 450
461 // Called by AudioPullFifo when more data is necessary. 451 // Called by AudioPullFifo when more data is necessary.
462 void WebRtcAudioRenderer::SourceCallback( 452 void WebRtcAudioRenderer::SourceCallback(
463 int fifo_frame_delay, media::AudioBus* audio_bus) { 453 int fifo_frame_delay, media::AudioBus* audio_bus) {
464 DCHECK(sink_->CurrentThreadIsRenderingThread()); 454 DCHECK(sink_->CurrentThreadIsRenderingThread());
465 base::TimeTicks start_time = base::TimeTicks::Now(); 455 base::TimeTicks start_time = base::TimeTicks::Now();
466 DVLOG(2) << "WebRtcAudioRenderer::SourceCallback(" 456 DVLOG(2) << "WebRtcAudioRenderer::SourceCallback("
467 << fifo_frame_delay << ", " 457 << fifo_frame_delay << ", "
468 << audio_bus->frames() << ")"; 458 << audio_bus->frames() << ")";
469 459
470 int output_delay_milliseconds = audio_delay_milliseconds_; 460 int output_delay_milliseconds = audio_delay_.InMilliseconds();
471 // TODO(grunell): This integer division by sample_rate will cause loss of 461 // TODO(grunell): This integer division by sample_rate will cause loss of
472 // partial milliseconds, and may cause avsync drift. http://crbug.com/586540 462 // partial milliseconds, and may cause avsync drift. http://crbug.com/586540
473 output_delay_milliseconds += fifo_frame_delay * 463 output_delay_milliseconds += fifo_frame_delay *
474 base::Time::kMillisecondsPerSecond / 464 base::Time::kMillisecondsPerSecond /
475 sink_params_.sample_rate(); 465 sink_params_.sample_rate();
476 DVLOG(2) << "output_delay_milliseconds: " << output_delay_milliseconds; 466 DVLOG(2) << "output_delay_milliseconds: " << output_delay_milliseconds;
477 467
478 // We need to keep render data for the |source_| regardless of |state_|, 468 // We need to keep render data for the |source_| regardless of |state_|,
479 // otherwise the data will be buffered up inside |source_|. 469 // otherwise the data will be buffered up inside |source_|.
480 source_->RenderData(audio_bus, sink_params_.sample_rate(), 470 source_->RenderData(audio_bus, sink_params_.sample_rate(),
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 sink_params_ = new_sink_params; 658 sink_params_ = new_sink_params;
669 } 659 }
670 660
671 // Specify the latency info to be passed to the browser side. 661 // Specify the latency info to be passed to the browser side.
672 new_sink_params.set_latency_tag(AudioDeviceFactory::GetSourceLatencyType( 662 new_sink_params.set_latency_tag(AudioDeviceFactory::GetSourceLatencyType(
673 AudioDeviceFactory::AudioDeviceFactory::kSourceWebRtc)); 663 AudioDeviceFactory::AudioDeviceFactory::kSourceWebRtc));
674 sink_->Initialize(new_sink_params, this); 664 sink_->Initialize(new_sink_params, this);
675 } 665 }
676 666
677 } // namespace content 667 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/webrtc_audio_renderer.h ('k') | media/audio/audio_output_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698