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

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

Issue 1596523005: Drop WebRTC audio data if OS has skipped frames. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Smaller fixes. Created 4 years, 11 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
« no previous file with comments | « content/renderer/media/webrtc_audio_renderer.h ('k') | media/base/audio_pull_fifo.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/logging.h" 9 #include "base/logging.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 const url::Origin& security_origin) 180 const url::Origin& security_origin)
181 : state_(UNINITIALIZED), 181 : state_(UNINITIALIZED),
182 source_render_frame_id_(source_render_frame_id), 182 source_render_frame_id_(source_render_frame_id),
183 session_id_(session_id), 183 session_id_(session_id),
184 signaling_thread_(signaling_thread), 184 signaling_thread_(signaling_thread),
185 media_stream_(media_stream), 185 media_stream_(media_stream),
186 source_(NULL), 186 source_(NULL),
187 play_ref_count_(0), 187 play_ref_count_(0),
188 start_ref_count_(0), 188 start_ref_count_(0),
189 audio_delay_milliseconds_(0), 189 audio_delay_milliseconds_(0),
190 fifo_delay_milliseconds_(0),
191 sink_params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 190 sink_params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
192 media::CHANNEL_LAYOUT_STEREO, 191 media::CHANNEL_LAYOUT_STEREO,
193 0, 192 0,
194 16, 193 16,
195 0), 194 0),
196 output_device_id_(device_id), 195 output_device_id_(device_id),
197 security_origin_(security_origin), 196 security_origin_(security_origin),
198 render_callback_count_(0) { 197 render_callback_count_(0) {
199 WebRtcLogMessage(base::StringPrintf( 198 WebRtcLogMessage(base::StringPrintf(
200 "WAR::WAR. source_render_frame_id=%d, session_id=%d, effects=%i", 199 "WAR::WAR. source_render_frame_id=%d, session_id=%d, effects=%i",
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 base::AutoLock auto_lock(lock_); 426 base::AutoLock auto_lock(lock_);
428 if (!source_) 427 if (!source_)
429 return 0; 428 return 0;
430 429
431 DVLOG(2) << "WebRtcAudioRenderer::Render()"; 430 DVLOG(2) << "WebRtcAudioRenderer::Render()";
432 DVLOG(2) << "audio_delay_milliseconds: " << audio_delay_milliseconds; 431 DVLOG(2) << "audio_delay_milliseconds: " << audio_delay_milliseconds;
433 432
434 DCHECK_LE(audio_delay_milliseconds, static_cast<uint32_t>(INT_MAX)); 433 DCHECK_LE(audio_delay_milliseconds, static_cast<uint32_t>(INT_MAX));
435 audio_delay_milliseconds_ = static_cast<int>(audio_delay_milliseconds); 434 audio_delay_milliseconds_ = static_cast<int>(audio_delay_milliseconds);
436 435
436 // If there are skipped frames, pull and throw away the same amount.
437 if (frames_skipped > 0) {
438 const uint32_t frames_per_10ms =
439 static_cast<uint32_t>(sink_params_.sample_rate() / 100);
440 if (!audio_fifo_ && frames_skipped != frames_per_10ms) {
441 audio_fifo_.reset(new media::AudioPullFifo(
442 sink_params_.channels(), frames_per_10ms,
443 base::Bind(&WebRtcAudioRenderer::SourceCallback,
444 base::Unretained(this))));
445 }
446
447 scoped_ptr<media::AudioBus> drop_bus =
448 media::AudioBus::Create(audio_bus->channels(), frames_skipped);
449 if (audio_fifo_)
450 audio_fifo_->Consume(drop_bus.get(), drop_bus->frames());
451 else
452 SourceCallback(0, drop_bus.get());
453 }
454
455 // Pull the data we shall deliver.
tommi (sloooow) - chröme 2016/01/15 18:50:03 nit: s/shall/will
Henrik Grunell 2016/01/18 13:00:54 Done.
437 if (audio_fifo_) 456 if (audio_fifo_)
438 audio_fifo_->Consume(audio_bus, audio_bus->frames()); 457 audio_fifo_->Consume(audio_bus, audio_bus->frames());
439 else 458 else
440 SourceCallback(0, audio_bus); 459 SourceCallback(0, audio_bus);
441 460
442 return (state_ == PLAYING) ? audio_bus->frames() : 0; 461 return (state_ == PLAYING) ? audio_bus->frames() : 0;
443 } 462 }
444 463
445 void WebRtcAudioRenderer::OnRenderError() { 464 void WebRtcAudioRenderer::OnRenderError() {
446 NOTIMPLEMENTED(); 465 NOTIMPLEMENTED();
447 LOG(ERROR) << "OnRenderError()"; 466 LOG(ERROR) << "OnRenderError()";
448 } 467 }
449 468
450 // Called by AudioPullFifo when more data is necessary. 469 // Called by AudioPullFifo when more data is necessary.
451 void WebRtcAudioRenderer::SourceCallback( 470 void WebRtcAudioRenderer::SourceCallback(
452 int fifo_frame_delay, media::AudioBus* audio_bus) { 471 int fifo_frame_delay, media::AudioBus* audio_bus) {
453 DCHECK(audio_renderer_thread_checker_.CalledOnValidThread()); 472 DCHECK(audio_renderer_thread_checker_.CalledOnValidThread());
454 base::TimeTicks start_time = base::TimeTicks::Now(); 473 base::TimeTicks start_time = base::TimeTicks::Now();
455 DVLOG(2) << "WebRtcAudioRenderer::SourceCallback(" 474 DVLOG(2) << "WebRtcAudioRenderer::SourceCallback("
456 << fifo_frame_delay << ", " 475 << fifo_frame_delay << ", "
457 << audio_bus->frames() << ")"; 476 << audio_bus->frames() << ")";
458 477
459 int output_delay_milliseconds = audio_delay_milliseconds_; 478 int output_delay_milliseconds = audio_delay_milliseconds_;
460 output_delay_milliseconds += fifo_delay_milliseconds_; 479 output_delay_milliseconds += fifo_frame_delay *
480 base::Time::kMillisecondsPerSecond /
481 sink_params_.sample_rate();
461 DVLOG(2) << "output_delay_milliseconds: " << output_delay_milliseconds; 482 DVLOG(2) << "output_delay_milliseconds: " << output_delay_milliseconds;
462 483
463 // We need to keep render data for the |source_| regardless of |state_|, 484 // We need to keep render data for the |source_| regardless of |state_|,
464 // otherwise the data will be buffered up inside |source_|. 485 // otherwise the data will be buffered up inside |source_|.
465 source_->RenderData(audio_bus, sink_params_.sample_rate(), 486 source_->RenderData(audio_bus, sink_params_.sample_rate(),
466 output_delay_milliseconds, 487 output_delay_milliseconds,
467 &current_time_); 488 &current_time_);
468 489
469 // Avoid filling up the audio bus if we are not playing; instead 490 // Avoid filling up the audio bus if we are not playing; instead
470 // return here and ensure that the returned value in Render() is 0. 491 // return here and ensure that the returned value in Render() is 0.
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 const int frames_per_buffer = GetOptimalBufferSize( 641 const int frames_per_buffer = GetOptimalBufferSize(
621 sample_rate, sink_->GetOutputParameters().frames_per_buffer()); 642 sample_rate, sink_->GetOutputParameters().frames_per_buffer());
622 643
623 new_sink_params.Reset( 644 new_sink_params.Reset(
624 new_sink_params.format(), new_sink_params.channel_layout(), 645 new_sink_params.format(), new_sink_params.channel_layout(),
625 sample_rate, 16, frames_per_buffer); 646 sample_rate, 16, frames_per_buffer);
626 647
627 // Create a FIFO if re-buffering is required to match the source input with 648 // Create a FIFO if re-buffering is required to match the source input with
628 // the sink request. The source acts as provider here and the sink as 649 // the sink request. The source acts as provider here and the sink as
629 // consumer. 650 // consumer.
630 int new_fifo_delay_milliseconds = 0;
631 scoped_ptr<media::AudioPullFifo> new_audio_fifo; 651 scoped_ptr<media::AudioPullFifo> new_audio_fifo;
632 if (source_params.frames_per_buffer() != 652 DCHECK_EQ(source_params.channels(),
633 new_sink_params.frames_per_buffer()) { 653 media::ChannelLayoutToChannelCount(media::CHANNEL_LAYOUT_STEREO));
tommi (sloooow) - chröme 2016/01/15 18:50:03 new assumption or did the previous code assume thi
Henrik Grunell 2016/01/18 13:00:54 Actually, the assumption is that source and sink o
654 const bool different_source_sink_frames =
655 source_params.frames_per_buffer() != new_sink_params.frames_per_buffer();
656 if (different_source_sink_frames) {
634 DVLOG(1) << "Rebuffering from " << source_params.frames_per_buffer() 657 DVLOG(1) << "Rebuffering from " << source_params.frames_per_buffer()
635 << " to " << new_sink_params.frames_per_buffer(); 658 << " to " << new_sink_params.frames_per_buffer();
636 new_audio_fifo.reset(new media::AudioPullFifo(
637 source_params.channels(), source_params.frames_per_buffer(),
638 base::Bind(&WebRtcAudioRenderer::SourceCallback,
639 base::Unretained(this))));
640
641 if (new_sink_params.frames_per_buffer() >
642 source_params.frames_per_buffer()) {
643 int frame_duration_milliseconds =
644 base::Time::kMillisecondsPerSecond /
645 static_cast<double>(source_params.sample_rate());
646 new_fifo_delay_milliseconds = (new_sink_params.frames_per_buffer() -
647 source_params.frames_per_buffer()) *
648 frame_duration_milliseconds;
649 }
650 } 659 }
651 660
652 { 661 {
653 base::AutoLock lock(lock_); 662 base::AutoLock lock(lock_);
663 const bool source_frames_changed =
664 audio_fifo_->SizeInFrames() != source_params.frames_per_buffer();
665 if ((!audio_fifo_ && different_source_sink_frames) ||
666 (audio_fifo_ && source_frames_changed)) {
667 audio_fifo_.reset(new media::AudioPullFifo(
668 source_params.channels(), source_params.frames_per_buffer(),
669 base::Bind(&WebRtcAudioRenderer::SourceCallback,
670 base::Unretained(this))));
671 }
654 sink_params_ = new_sink_params; 672 sink_params_ = new_sink_params;
655 fifo_delay_milliseconds_ = new_fifo_delay_milliseconds;
656 if (new_audio_fifo.get())
657 audio_fifo_ = std::move(new_audio_fifo);
658 } 673 }
659 674
660 sink_->Initialize(new_sink_params, this); 675 sink_->Initialize(new_sink_params, this);
661 } 676 }
662 677
663 } // namespace content 678 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/webrtc_audio_renderer.h ('k') | media/base/audio_pull_fifo.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698