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

Side by Side Diff: chromecast/media/cma/backend/alsa/stream_mixer_alsa_input_impl.cc

Issue 2722833003: Reland of [Chromecast] Process streams with different post-processing. (Closed)
Patch Set: Handle empty device_id as DefaultDevice Created 3 years, 9 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "chromecast/media/cma/backend/alsa/stream_mixer_alsa_input_impl.h" 5 #include "chromecast/media/cma/backend/alsa/stream_mixer_alsa_input_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 58
59 const int kMaxSlewTimeUpMs = 15; 59 const int kMaxSlewTimeUpMs = 15;
60 const int kMaxSlewTimeDownMs = 15; 60 const int kMaxSlewTimeDownMs = 15;
61 61
62 } // namespace 62 } // namespace
63 63
64 StreamMixerAlsaInputImpl::StreamMixerAlsaInputImpl( 64 StreamMixerAlsaInputImpl::StreamMixerAlsaInputImpl(
65 StreamMixerAlsaInput::Delegate* delegate, 65 StreamMixerAlsaInput::Delegate* delegate,
66 int input_samples_per_second, 66 int input_samples_per_second,
67 bool primary, 67 bool primary,
68 const std::string& device_id,
68 StreamMixerAlsa* mixer) 69 StreamMixerAlsa* mixer)
69 : delegate_(delegate), 70 : delegate_(delegate),
70 input_samples_per_second_(input_samples_per_second), 71 input_samples_per_second_(input_samples_per_second),
71 primary_(primary), 72 primary_(primary),
73 device_id_(device_id),
72 mixer_(mixer), 74 mixer_(mixer),
75 filter_group_(nullptr),
73 mixer_task_runner_(mixer_->task_runner()), 76 mixer_task_runner_(mixer_->task_runner()),
74 caller_task_runner_(base::ThreadTaskRunnerHandle::Get()), 77 caller_task_runner_(base::ThreadTaskRunnerHandle::Get()),
75 resample_ratio_(1.0), 78 resample_ratio_(1.0),
76 state_(kStateUninitialized), 79 state_(kStateUninitialized),
77 slew_volume_(kMaxSlewTimeUpMs, kMaxSlewTimeDownMs), 80 slew_volume_(kMaxSlewTimeUpMs, kMaxSlewTimeDownMs),
78 queued_frames_(0), 81 queued_frames_(0),
79 queued_frames_including_resampler_(0), 82 queued_frames_including_resampler_(0),
80 current_buffer_offset_(0), 83 current_buffer_offset_(0),
81 max_queued_frames_(kMaxInputQueueUs * input_samples_per_second / 84 max_queued_frames_(kMaxInputQueueUs * input_samples_per_second /
82 base::Time::kMicrosecondsPerSecond), 85 base::Time::kMicrosecondsPerSecond),
83 fade_frames_remaining_(0), 86 fade_frames_remaining_(0),
84 fade_out_frames_total_(0), 87 fade_out_frames_total_(0),
85 zeroed_frames_(0), 88 zeroed_frames_(0),
86 is_underflowing_(false), 89 is_underflowing_(false),
87 weak_factory_(this) { 90 weak_factory_(this) {
88 LOG(INFO) << "Create " << this; 91 LOG(INFO) << "Create " << device_id_ << " (" << this << ")";
89 DCHECK(delegate_); 92 DCHECK(delegate_);
90 DCHECK(mixer_); 93 DCHECK(mixer_);
91 weak_this_ = weak_factory_.GetWeakPtr(); 94 weak_this_ = weak_factory_.GetWeakPtr();
92 } 95 }
93 96
94 StreamMixerAlsaInputImpl::~StreamMixerAlsaInputImpl() { 97 StreamMixerAlsaInputImpl::~StreamMixerAlsaInputImpl() {
95 LOG(INFO) << "Destroy " << this; 98 LOG(INFO) << "Destroy " << device_id_ << " (" << this << ")";
96 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); 99 DCHECK(mixer_task_runner_->BelongsToCurrentThread());
97 } 100 }
98 101
99 int StreamMixerAlsaInputImpl::input_samples_per_second() const { 102 int StreamMixerAlsaInputImpl::input_samples_per_second() const {
100 return input_samples_per_second_; 103 return input_samples_per_second_;
101 } 104 }
102 105
103 bool StreamMixerAlsaInputImpl::primary() const { 106 bool StreamMixerAlsaInputImpl::primary() const {
104 return primary_; 107 return primary_;
105 } 108 }
106 109
110 std::string StreamMixerAlsaInputImpl::device_id() const {
111 return device_id_;
112 }
113
107 bool StreamMixerAlsaInputImpl::IsDeleting() const { 114 bool StreamMixerAlsaInputImpl::IsDeleting() const {
108 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); 115 DCHECK(mixer_task_runner_->BelongsToCurrentThread());
109 return (state_ == kStateFinalFade || state_ == kStateDeleted); 116 return (state_ == kStateFinalFade || state_ == kStateDeleted);
110 } 117 }
111 118
112 void StreamMixerAlsaInputImpl::Initialize( 119 void StreamMixerAlsaInputImpl::Initialize(
113 const MediaPipelineBackendAlsa::RenderingDelay& mixer_rendering_delay) { 120 const MediaPipelineBackendAlsa::RenderingDelay& mixer_rendering_delay) {
114 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); 121 DCHECK(mixer_task_runner_->BelongsToCurrentThread());
115 DCHECK(!IsDeleting()); 122 DCHECK(!IsDeleting());
116 if (mixer_->output_samples_per_second() != input_samples_per_second_) { 123 if (mixer_->output_samples_per_second() != input_samples_per_second_) {
117 resample_ratio_ = static_cast<double>(input_samples_per_second_) / 124 resample_ratio_ = static_cast<double>(input_samples_per_second_) /
118 mixer_->output_samples_per_second(); 125 mixer_->output_samples_per_second();
119 resampler_.reset(new ::media::MultiChannelResampler( 126 resampler_.reset(new ::media::MultiChannelResampler(
120 kNumOutputChannels, resample_ratio_, kDefaultReadSize, 127 kNumOutputChannels, resample_ratio_, kDefaultReadSize,
121 base::Bind(&StreamMixerAlsaInputImpl::ReadCB, base::Unretained(this)))); 128 base::Bind(&StreamMixerAlsaInputImpl::ReadCB, base::Unretained(this))));
122 resampler_->PrimeWithSilence(); 129 resampler_->PrimeWithSilence();
123 } 130 }
124 slew_volume_.SetSampleRate(mixer_->output_samples_per_second()); 131 slew_volume_.SetSampleRate(mixer_->output_samples_per_second());
125 mixer_rendering_delay_ = mixer_rendering_delay; 132 mixer_rendering_delay_ = mixer_rendering_delay;
126 fade_out_frames_total_ = NormalFadeFrames(); 133 fade_out_frames_total_ = NormalFadeFrames();
127 fade_frames_remaining_ = NormalFadeFrames(); 134 fade_frames_remaining_ = NormalFadeFrames();
128 } 135 }
129 136
137 void StreamMixerAlsaInputImpl::set_filter_group(FilterGroup* filter_group) {
138 filter_group_ = filter_group;
139 }
140
141 FilterGroup* StreamMixerAlsaInputImpl::filter_group() {
142 return filter_group_;
143 }
144
130 void StreamMixerAlsaInputImpl::PreventDelegateCalls() { 145 void StreamMixerAlsaInputImpl::PreventDelegateCalls() {
131 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 146 DCHECK(caller_task_runner_->BelongsToCurrentThread());
132 weak_factory_.InvalidateWeakPtrs(); 147 weak_factory_.InvalidateWeakPtrs();
133 148
134 base::AutoLock lock(queue_lock_); 149 base::AutoLock lock(queue_lock_);
135 pending_data_ = nullptr; 150 pending_data_ = nullptr;
136 } 151 }
137 152
138 void StreamMixerAlsaInputImpl::PrepareToDelete( 153 void StreamMixerAlsaInputImpl::PrepareToDelete(
139 const OnReadyToDeleteCb& delete_cb) { 154 const OnReadyToDeleteCb& delete_cb) {
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 int StreamMixerAlsaInputImpl::NormalFadeFrames() { 434 int StreamMixerAlsaInputImpl::NormalFadeFrames() {
420 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); 435 DCHECK(mixer_task_runner_->BelongsToCurrentThread());
421 int frames = (mixer_->output_samples_per_second() * kFadeMs / 436 int frames = (mixer_->output_samples_per_second() * kFadeMs /
422 base::Time::kMillisecondsPerSecond) - 437 base::Time::kMillisecondsPerSecond) -
423 1; 438 1;
424 return std::max(frames, 0); 439 return std::max(frames, 0);
425 } 440 }
426 441
427 void StreamMixerAlsaInputImpl::FadeIn(::media::AudioBus* dest, int frames) { 442 void StreamMixerAlsaInputImpl::FadeIn(::media::AudioBus* dest, int frames) {
428 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); 443 DCHECK(mixer_task_runner_->BelongsToCurrentThread());
429 LOG(INFO) << "Fading in, " << fade_frames_remaining_ << " frames remaining";
430 float fade_in_frames = mixer_->output_samples_per_second() * kFadeMs / 444 float fade_in_frames = mixer_->output_samples_per_second() * kFadeMs /
431 base::Time::kMillisecondsPerSecond; 445 base::Time::kMillisecondsPerSecond;
432 for (int f = 0; f < frames && fade_frames_remaining_; ++f) { 446 for (int f = 0; f < frames && fade_frames_remaining_; ++f) {
433 float fade_multiplier = 1.0 - fade_frames_remaining_ / fade_in_frames; 447 float fade_multiplier = 1.0 - fade_frames_remaining_ / fade_in_frames;
434 for (int c = 0; c < kNumOutputChannels; ++c) 448 for (int c = 0; c < kNumOutputChannels; ++c)
435 dest->channel(c)[f] *= fade_multiplier; 449 dest->channel(c)[f] *= fade_multiplier;
436 --fade_frames_remaining_; 450 --fade_frames_remaining_;
437 } 451 }
438 } 452 }
439 453
440 void StreamMixerAlsaInputImpl::FadeOut(::media::AudioBus* dest, int frames) { 454 void StreamMixerAlsaInputImpl::FadeOut(::media::AudioBus* dest, int frames) {
441 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); 455 DCHECK(mixer_task_runner_->BelongsToCurrentThread());
442 LOG(INFO) << "Fading out, " << fade_frames_remaining_ << " frames remaining";
443 int f = 0; 456 int f = 0;
444 for (; f < frames && fade_frames_remaining_; ++f) { 457 for (; f < frames && fade_frames_remaining_; ++f) {
445 float fade_multiplier = 458 float fade_multiplier =
446 fade_frames_remaining_ / static_cast<float>(fade_out_frames_total_); 459 fade_frames_remaining_ / static_cast<float>(fade_out_frames_total_);
447 for (int c = 0; c < kNumOutputChannels; ++c) 460 for (int c = 0; c < kNumOutputChannels; ++c)
448 dest->channel(c)[f] *= fade_multiplier; 461 dest->channel(c)[f] *= fade_multiplier;
449 --fade_frames_remaining_; 462 --fade_frames_remaining_;
450 } 463 }
451 // Zero remaining frames 464 // Zero remaining frames
452 for (; f < frames; ++f) { 465 for (; f < frames; ++f) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 521
509 if (state_ == kStateFadingOut) { 522 if (state_ == kStateFadingOut) {
510 // Tell the mixer that some more data might be available (since when fading 523 // Tell the mixer that some more data might be available (since when fading
511 // out, we can drain the queue completely). 524 // out, we can drain the queue completely).
512 mixer_->OnFramesQueued(); 525 mixer_->OnFramesQueued();
513 } 526 }
514 } 527 }
515 528
516 void StreamMixerAlsaInputImpl::SetVolumeMultiplier(float multiplier) { 529 void StreamMixerAlsaInputImpl::SetVolumeMultiplier(float multiplier) {
517 RUN_ON_MIXER_THREAD(SetVolumeMultiplier, multiplier); 530 RUN_ON_MIXER_THREAD(SetVolumeMultiplier, multiplier);
518 LOG(INFO) << this << ": stream volume = " << multiplier; 531 LOG(INFO) << device_id_ << "(" << this << "): stream volume = " << multiplier;
519 DCHECK(!IsDeleting()); 532 DCHECK(!IsDeleting());
520 if (multiplier > 1.0f) 533 if (multiplier > 1.0f)
521 multiplier = 1.0f; 534 multiplier = 1.0f;
522 if (multiplier < 0.0f) 535 if (multiplier < 0.0f)
523 multiplier = 0.0f; 536 multiplier = 0.0f;
524 slew_volume_.SetVolume(multiplier); 537 slew_volume_.SetVolume(multiplier);
525 } 538 }
526 539
527 void StreamMixerAlsaInputImpl::VolumeScaleAccumulate(bool repeat_transition, 540 void StreamMixerAlsaInputImpl::VolumeScaleAccumulate(bool repeat_transition,
528 const float* src, 541 const float* src,
529 int frames, 542 int frames,
530 float* dest) { 543 float* dest) {
531 slew_volume_.ProcessFMAC(repeat_transition, src, frames, dest); 544 slew_volume_.ProcessFMAC(repeat_transition, src, frames, dest);
532 } 545 }
533 546
534 } // namespace media 547 } // namespace media
535 } // namespace chromecast 548 } // namespace chromecast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698