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

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

Issue 2771143002: Implement runtime audio post-processing pipeline. See go/cast_audio.json (Closed)
Patch Set: Suffix governor with _1.0 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
« no previous file with comments | « chromecast/media/cma/backend/alsa/stream_mixer_alsa.h ('k') | chromecast/public/media/BUILD.gn » ('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 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.h" 5 #include "chromecast/media/cma/backend/alsa/stream_mixer_alsa.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 #include <unordered_set> 10 #include <unordered_set>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/lazy_instance.h" 15 #include "base/lazy_instance.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/memory/weak_ptr.h" 17 #include "base/memory/weak_ptr.h"
18 #include "base/numerics/saturated_arithmetic.h" 18 #include "base/numerics/saturated_arithmetic.h"
19 #include "base/single_thread_task_runner.h" 19 #include "base/single_thread_task_runner.h"
20 #include "base/threading/platform_thread.h" 20 #include "base/threading/platform_thread.h"
21 #include "base/threading/thread_task_runner_handle.h" 21 #include "base/threading/thread_task_runner_handle.h"
22 #include "chromecast/base/chromecast_switches.h" 22 #include "chromecast/base/chromecast_switches.h"
23 #include "chromecast/media/base/audio_device_ids.h" 23 #include "chromecast/media/base/audio_device_ids.h"
24 #include "chromecast/media/cma/backend/alsa/alsa_wrapper.h" 24 #include "chromecast/media/cma/backend/alsa/alsa_wrapper.h"
25 #include "chromecast/media/cma/backend/alsa/audio_filter_factory.h"
26 #include "chromecast/media/cma/backend/alsa/filter_group.h" 25 #include "chromecast/media/cma/backend/alsa/filter_group.h"
26 #include "chromecast/media/cma/backend/alsa/post_processing_pipeline_parser.h"
27 #include "chromecast/media/cma/backend/alsa/stream_mixer_alsa_input_impl.h" 27 #include "chromecast/media/cma/backend/alsa/stream_mixer_alsa_input_impl.h"
28 #include "media/audio/audio_device_description.h" 28 #include "media/audio/audio_device_description.h"
29 #include "media/base/audio_bus.h" 29 #include "media/base/audio_bus.h"
30 #include "media/base/media_switches.h" 30 #include "media/base/media_switches.h"
31 31
32 #define RETURN_REPORT_ERROR(snd_func, ...) \ 32 #define RETURN_REPORT_ERROR(snd_func, ...) \
33 do { \ 33 do { \
34 int err = alsa_->snd_func(__VA_ARGS__); \ 34 int err = alsa_->snd_func(__VA_ARGS__); \
35 if (err < 0) { \ 35 if (err < 0) { \
36 LOG(ERROR) << #snd_func " error: " << alsa_->StrError(err); \ 36 LOG(ERROR) << #snd_func " error: " << alsa_->StrError(err); \
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 LOG(INFO) << "Setting fixed sample rate to " << fixed_samples_per_second; 208 LOG(INFO) << "Setting fixed sample rate to " << fixed_samples_per_second;
209 } 209 }
210 210
211 fixed_output_samples_per_second_ = fixed_samples_per_second; 211 fixed_output_samples_per_second_ = fixed_samples_per_second;
212 212
213 low_sample_rate_cutoff_ = 213 low_sample_rate_cutoff_ =
214 chromecast::GetSwitchValueBoolean(switches::kAlsaEnableUpsampling, false) 214 chromecast::GetSwitchValueBoolean(switches::kAlsaEnableUpsampling, false)
215 ? kLowSampleRateCutoff 215 ? kLowSampleRateCutoff
216 : 0; 216 : 0;
217 217
218 // Read post-processing configuration file
219 PostProcessingPipelineParser pipeline_parser;
220 pipeline_parser.Initialize();
221
218 // Create filter groups. 222 // Create filter groups.
219 // TODO(bshaya): Switch to filter groups based on AudioContentType. 223 // TODO(bshaya): Switch to filter groups based on AudioContentType.
220 filter_groups_.push_back(base::MakeUnique<FilterGroup>( 224 filter_groups_.push_back(base::MakeUnique<FilterGroup>(
221 std::unordered_set<std::string>( 225 std::unordered_set<std::string>(
222 {::media::AudioDeviceDescription::kCommunicationsDeviceId}), 226 {::media::AudioDeviceDescription::kCommunicationsDeviceId}),
223 AudioFilterFactory::COMMUNICATION_AUDIO_FILTER, 227 AudioContentType::kMedia, kNumOutputChannels,
224 AudioContentType::kMedia)); 228 pipeline_parser.GetPipelineByDeviceId(
229 ::media::AudioDeviceDescription::kCommunicationsDeviceId)));
225 filter_groups_.push_back(base::MakeUnique<FilterGroup>( 230 filter_groups_.push_back(base::MakeUnique<FilterGroup>(
226 std::unordered_set<std::string>({kAlarmAudioDeviceId}), 231 std::unordered_set<std::string>({kAlarmAudioDeviceId}),
227 AudioFilterFactory::ALARM_AUDIO_FILTER, AudioContentType::kAlarm)); 232 AudioContentType::kAlarm, kNumOutputChannels,
233 pipeline_parser.GetPipelineByDeviceId(kAlarmAudioDeviceId)));
228 filter_groups_.push_back(base::MakeUnique<FilterGroup>( 234 filter_groups_.push_back(base::MakeUnique<FilterGroup>(
229 std::unordered_set<std::string>({kTtsAudioDeviceId}), 235 std::unordered_set<std::string>({kTtsAudioDeviceId}),
230 AudioFilterFactory::TTS_AUDIO_FILTER, AudioContentType::kCommunication)); 236 AudioContentType::kCommunication, kNumOutputChannels,
237 pipeline_parser.GetPipelineByDeviceId(kTtsAudioDeviceId)));
231 filter_groups_.push_back(base::MakeUnique<FilterGroup>( 238 filter_groups_.push_back(base::MakeUnique<FilterGroup>(
232 std::unordered_set<std::string>( 239 std::unordered_set<std::string>(
233 {::media::AudioDeviceDescription::kDefaultDeviceId, 240 {::media::AudioDeviceDescription::kDefaultDeviceId,
234 kLocalAudioDeviceId, ""}), 241 kLocalAudioDeviceId, ""}),
235 AudioFilterFactory::MEDIA_AUDIO_FILTER, AudioContentType::kMedia)); 242 AudioContentType::kMedia, kNumOutputChannels,
243 pipeline_parser.GetPipelineByDeviceId(
244 ::media::AudioDeviceDescription::kDefaultDeviceId)));
236 245
246 // TODO(bshaya): Add support for final mix AudioPostProcessor.
237 DefineAlsaParameters(); 247 DefineAlsaParameters();
238 } 248 }
239 249
240 void StreamMixerAlsa::ResetTaskRunnerForTest() { 250 void StreamMixerAlsa::ResetTaskRunnerForTest() {
241 mixer_task_runner_ = base::ThreadTaskRunnerHandle::Get(); 251 mixer_task_runner_ = base::ThreadTaskRunnerHandle::Get();
242 } 252 }
243 253
244 void StreamMixerAlsa::DefineAlsaParameters() { 254 void StreamMixerAlsa::DefineAlsaParameters() {
245 // Get the ALSA output configuration from the command line. 255 // Get the ALSA output configuration from the command line.
246 alsa_buffer_size_ = GetSwitchValueNonNegativeInt( 256 alsa_buffer_size_ = GetSwitchValueNonNegativeInt(
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 if (err < 0) { 502 if (err < 0) {
493 LOG(ERROR) << "Error setting ALSA playback parameters: " 503 LOG(ERROR) << "Error setting ALSA playback parameters: "
494 << alsa_->StrError(err); 504 << alsa_->StrError(err);
495 SignalError(); 505 SignalError();
496 return; 506 return;
497 } 507 }
498 } 508 }
499 509
500 // Initialize filters 510 // Initialize filters
501 for (auto&& filter_group : filter_groups_) { 511 for (auto&& filter_group : filter_groups_) {
502 filter_group->Initialize(output_samples_per_second_, 512 filter_group->Initialize(output_samples_per_second_);
503 ::media::SampleFormat::kSampleFormatS32);
504 } 513 }
505 514
506 RETURN_REPORT_ERROR(PcmPrepare, pcm_); 515 RETURN_REPORT_ERROR(PcmPrepare, pcm_);
507 RETURN_REPORT_ERROR(PcmStatusMalloc, &pcm_status_); 516 RETURN_REPORT_ERROR(PcmStatusMalloc, &pcm_status_);
508 517
509 rendering_delay_.timestamp_microseconds = kNoTimestamp; 518 rendering_delay_.timestamp_microseconds = kNoTimestamp;
510 rendering_delay_.delay_microseconds = 0; 519 rendering_delay_.delay_microseconds = 0;
511 520
512 state_ = kStateNormalPlayback; 521 state_ = kStateNormalPlayback;
513 } 522 }
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 } 889 }
881 UpdateRenderingDelay(frames); 890 UpdateRenderingDelay(frames);
882 for (auto&& input : inputs_) 891 for (auto&& input : inputs_)
883 input->AfterWriteFrames(rendering_delay_); 892 input->AfterWriteFrames(rendering_delay_);
884 } 893 }
885 894
886 void StreamMixerAlsa::UpdateRenderingDelay(int newly_pushed_frames) { 895 void StreamMixerAlsa::UpdateRenderingDelay(int newly_pushed_frames) {
887 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); 896 DCHECK(mixer_task_runner_->BelongsToCurrentThread());
888 CHECK_PCM_INITIALIZED(); 897 CHECK_PCM_INITIALIZED();
889 898
899 // TODO(bshaya): Add rendering delay from post-processors.
890 if (alsa_->PcmStatus(pcm_, pcm_status_) != 0 || 900 if (alsa_->PcmStatus(pcm_, pcm_status_) != 0 ||
891 alsa_->PcmStatusGetState(pcm_status_) != SND_PCM_STATE_RUNNING) { 901 alsa_->PcmStatusGetState(pcm_status_) != SND_PCM_STATE_RUNNING) {
892 rendering_delay_.timestamp_microseconds = kNoTimestamp; 902 rendering_delay_.timestamp_microseconds = kNoTimestamp;
893 rendering_delay_.delay_microseconds = 0; 903 rendering_delay_.delay_microseconds = 0;
894 return; 904 return;
895 } 905 }
896 906
897 snd_htimestamp_t status_timestamp = {}; 907 snd_htimestamp_t status_timestamp = {};
898 alsa_->PcmStatusGetHtstamp(pcm_status_, &status_timestamp); 908 alsa_->PcmStatusGetHtstamp(pcm_status_, &status_timestamp);
899 rendering_delay_.timestamp_microseconds = 909 rendering_delay_.timestamp_microseconds =
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 989
980 for (auto&& filter : filter_groups_) { 990 for (auto&& filter : filter_groups_) {
981 if (filter->content_type() == type) { 991 if (filter->content_type() == type) {
982 filter->set_volume(effective_volume); 992 filter->set_volume(effective_volume);
983 } 993 }
984 } 994 }
985 } 995 }
986 996
987 } // namespace media 997 } // namespace media
988 } // namespace chromecast 998 } // namespace chromecast
OLDNEW
« no previous file with comments | « chromecast/media/cma/backend/alsa/stream_mixer_alsa.h ('k') | chromecast/public/media/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698