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

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

Issue 2847673002: [Chromecast] Complete PostProcessingPipeline changes (Closed)
Patch Set: Fix deps Created 3 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
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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/post_processing_pipeline.h" 5 #include "chromecast/media/cma/backend/alsa/post_processing_pipeline_impl.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #include "base/scoped_native_library.h" 11 #include "base/scoped_native_library.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "chromecast/base/serializers.h" 13 #include "chromecast/base/serializers.h"
14 #include "chromecast/public/media/audio_post_processor_shlib.h" 14 #include "chromecast/public/media/audio_post_processor_shlib.h"
15 #include "chromecast/public/volume_control.h"
15 16
16 namespace chromecast { 17 namespace chromecast {
17 namespace media { 18 namespace media {
18 19
19 namespace { 20 namespace {
20 21
21 const int kNoSampleRate = -1; 22 const int kNoSampleRate = -1;
22 const char kSoCreateFunction[] = "AudioPostProcessorShlib_Create"; 23 const char kSoCreateFunction[] = "AudioPostProcessorShlib_Create";
24 const char kProcessorKey[] = "processor";
23 25
24 } // namespace 26 } // namespace
25 27
26 using CreatePostProcessor = AudioPostProcessor* (*)(const std::string&, int); 28 using CreatePostProcessor = AudioPostProcessor* (*)(const std::string&, int);
27 29
28 PostProcessingPipeline::PostProcessingPipeline( 30 std::unique_ptr<PostProcessingPipeline> PostProcessingPipeline::Create(
31 const std::string& name,
32 const base::ListValue* filter_description_list,
33 int num_channels) {
34 return base::MakeUnique<PostProcessingPipelineImpl>(
35 name, filter_description_list, num_channels);
36 }
37
38 PostProcessingPipelineImpl::PostProcessingPipelineImpl(
39 const std::string& name,
29 const base::ListValue* filter_description_list, 40 const base::ListValue* filter_description_list,
30 int channels) 41 int channels)
31 : sample_rate_(kNoSampleRate) { 42 : name_(name), sample_rate_(kNoSampleRate) {
32 if (!filter_description_list) { 43 if (!filter_description_list) {
33 return; // Warning logged. 44 return; // Warning logged.
34 } 45 }
35 for (size_t i = 0; i < filter_description_list->GetSize(); ++i) { 46 for (size_t i = 0; i < filter_description_list->GetSize(); ++i) {
36 const base::DictionaryValue* processor_description_dict; 47 const base::DictionaryValue* processor_description_dict;
37 CHECK( 48 CHECK(
38 filter_description_list->GetDictionary(i, &processor_description_dict)); 49 filter_description_list->GetDictionary(i, &processor_description_dict));
39 std::string library_path; 50 std::string library_path;
40 CHECK(processor_description_dict->GetString("processor", &library_path)); 51 CHECK(processor_description_dict->GetString(kProcessorKey, &library_path));
41 if (library_path == "null" || library_path == "none") { 52 if (library_path == "null" || library_path == "none") {
42 continue; 53 continue;
43 } 54 }
44 const base::Value* processor_config_val; 55 const base::Value* processor_config_val;
45 CHECK(processor_description_dict->Get("config", &processor_config_val)); 56 CHECK(processor_description_dict->Get("config", &processor_config_val));
46 CHECK(processor_config_val->is_dict() || processor_config_val->is_string()); 57 CHECK(processor_config_val->is_dict() || processor_config_val->is_string());
47 auto processor_config_string = SerializeToJson(*processor_config_val); 58 auto processor_config_string = SerializeToJson(*processor_config_val);
48 59
49 LOG(INFO) << "Creating an instance of " << library_path << "(" 60 LOG(INFO) << "Creating an instance of " << library_path << "("
50 << *processor_config_string << ")"; 61 << *processor_config_string << ")";
51 libraries_.push_back(base::MakeUnique<base::ScopedNativeLibrary>( 62 libraries_.push_back(base::MakeUnique<base::ScopedNativeLibrary>(
52 base::FilePath(library_path))); 63 base::FilePath(library_path)));
53 CHECK(libraries_.back()->is_valid()) 64 CHECK(libraries_.back()->is_valid())
54 << "Could not open post processing library " << library_path; 65 << "Could not open post processing library " << library_path;
55 CreatePostProcessor create = reinterpret_cast<CreatePostProcessor>( 66 CreatePostProcessor create = reinterpret_cast<CreatePostProcessor>(
56 libraries_.back()->GetFunctionPointer(kSoCreateFunction)); 67 libraries_.back()->GetFunctionPointer(kSoCreateFunction));
57 68
58 CHECK(create) << "Could not find " << kSoCreateFunction << "() in " 69 CHECK(create) << "Could not find " << kSoCreateFunction << "() in "
59 << library_path; 70 << library_path;
60 processors_.push_back( 71 processors_.push_back(
61 base::WrapUnique(create(*processor_config_string, channels))); 72 base::WrapUnique(create(*processor_config_string, channels)));
62 } 73 }
63 } 74 }
64 75
65 PostProcessingPipeline::~PostProcessingPipeline() = default; 76 PostProcessingPipelineImpl::~PostProcessingPipelineImpl() = default;
66 77
67 int PostProcessingPipeline::ProcessFrames(const std::vector<float*>& data, 78 int PostProcessingPipelineImpl::ProcessFrames(const std::vector<float*>& data,
68 int num_frames, 79 int num_frames,
69 float current_volume, 80 float current_multiplier,
70 bool is_silence) { 81 bool is_silence) {
71 DCHECK_NE(sample_rate_, kNoSampleRate); 82 DCHECK_NE(sample_rate_, kNoSampleRate);
72 if (is_silence) { 83 if (is_silence) {
73 if (!IsRinging()) { 84 if (!IsRinging()) {
74 return total_delay_frames_; // Output will be silence. 85 return total_delay_frames_; // Output will be silence.
75 } 86 }
76 silence_frames_processed_ += num_frames; 87 silence_frames_processed_ += num_frames;
77 } else { 88 } else {
78 silence_frames_processed_ = 0; 89 silence_frames_processed_ = 0;
79 } 90 }
80 91
92 UpdateCastVolume(current_multiplier);
93
81 total_delay_frames_ = 0; 94 total_delay_frames_ = 0;
82 for (auto& processor : processors_) { 95 for (auto& processor : processors_) {
83 total_delay_frames_ += 96 total_delay_frames_ +=
84 processor->ProcessFrames(data, num_frames, current_volume); 97 processor->ProcessFrames(data, num_frames, cast_volume_);
85 } 98 }
86 return total_delay_frames_; 99 return total_delay_frames_;
87 } 100 }
88 101
89 bool PostProcessingPipeline::SetSampleRate(int sample_rate) { 102 bool PostProcessingPipelineImpl::SetSampleRate(int sample_rate) {
90 sample_rate_ = sample_rate; 103 sample_rate_ = sample_rate;
91 bool result = true; 104 bool result = true;
92 for (auto& processor : processors_) { 105 for (auto& processor : processors_) {
93 result &= processor->SetSampleRate(sample_rate_); 106 result &= processor->SetSampleRate(sample_rate_);
94 } 107 }
95 ringing_time_in_frames_ = GetRingingTimeInFrames(); 108 ringing_time_in_frames_ = GetRingingTimeInFrames();
96 silence_frames_processed_ = 0; 109 silence_frames_processed_ = 0;
97 return result; 110 return result;
98 } 111 }
99 112
100 bool PostProcessingPipeline::IsRinging() { 113 bool PostProcessingPipelineImpl::IsRinging() {
101 return silence_frames_processed_ < ringing_time_in_frames_; 114 return silence_frames_processed_ < ringing_time_in_frames_;
102 } 115 }
103 116
104 int PostProcessingPipeline::GetRingingTimeInFrames() { 117 int PostProcessingPipelineImpl::GetRingingTimeInFrames() {
105 int memory_frames = 0; 118 int memory_frames = 0;
106 for (auto& processor : processors_) { 119 for (auto& processor : processors_) {
107 memory_frames += processor->GetRingingTimeInFrames(); 120 memory_frames += processor->GetRingingTimeInFrames();
108 } 121 }
109 return memory_frames; 122 return memory_frames;
110 } 123 }
111 124
125 void PostProcessingPipelineImpl::UpdateCastVolume(float multiplier) {
126 DCHECK_GE(multiplier, 0.0);
127
128 if (multiplier == current_multiplier_) {
129 return;
130 }
131 current_multiplier_ = multiplier;
132 float dbfs = std::log10(multiplier) * 20;
133 DCHECK(chromecast::media::VolumeControl::DbFSToVolume);
134 cast_volume_ = chromecast::media::VolumeControl::DbFSToVolume(dbfs);
135 }
136
112 } // namespace media 137 } // namespace media
113 } // namespace chromecast 138 } // namespace chromecast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698