OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chromecast/media/cma/backend/alsa/post_processing_pipeline.h" | |
6 | |
7 #include <dlfcn.h> | |
8 | |
9 #include <string> | |
10 | |
11 #include "base/files/file_path.h" | |
12 #include "base/memory/ptr_util.h" | |
13 #include "base/scoped_native_library.h" | |
14 #include "base/values.h" | |
15 #include "chromecast/base/serializers.h" | |
16 #include "chromecast/public/media/audio_post_processor_shlib.h" | |
17 | |
18 namespace chromecast { | |
19 namespace media { | |
20 | |
21 namespace { | |
22 | |
23 const int kNoSampleRate = -1; | |
24 const char kSoCreateFunction[] = "AudioPostProcessorShlib_Create"; | |
25 | |
26 } // namespace | |
27 | |
28 using CreatePostProcessor = | |
29 std::unique_ptr<AudioPostProcessor> (*)(const std::string&, int); | |
30 | |
31 PostProcessingPipeline::PostProcessingPipeline( | |
32 const base::ListValue* filter_description_list, | |
33 int channels) | |
34 : sample_rate_(kNoSampleRate) { | |
35 if (!filter_description_list) { | |
36 return; // Warning logged. | |
37 } | |
38 for (size_t i = 0; i < filter_description_list->GetSize(); ++i) { | |
39 const base::DictionaryValue* processor_description_dict; | |
40 CHECK( | |
41 filter_description_list->GetDictionary(i, &processor_description_dict)); | |
42 std::string library_path; | |
43 CHECK(processor_description_dict->GetString("processor", &library_path)); | |
44 if (library_path == "null" || library_path == "none") { | |
45 continue; | |
46 } | |
47 const base::Value* processor_config_val; | |
48 CHECK(processor_description_dict->Get("config", &processor_config_val)); | |
49 CHECK(processor_config_val->is_dict() || processor_config_val->is_string()); | |
50 auto processor_config_string = SerializeToJson(*processor_config_val); | |
51 | |
52 LOG(INFO) << "Creating an instance of " << library_path << "(" | |
53 << *processor_config_string << ")"; | |
54 if (libraries_.find(library_path) == libraries_.end()) { | |
55 libraries_[library_path] = base::MakeUnique<base::ScopedNativeLibrary>( | |
56 base::FilePath(library_path)); | |
57 } | |
58 auto& library = libraries_[library_path]; | |
59 CHECK(library->is_valid()) << "Could not open post processing library " | |
60 << library_path << ": " << dlerror(); | |
61 CreatePostProcessor create = reinterpret_cast<CreatePostProcessor>( | |
62 library->GetFunctionPointer(kSoCreateFunction)); | |
63 | |
64 char* error; | |
65 CHECK(!(error = dlerror())) << "Could not find " << kSoCreateFunction | |
kmackay
2017/03/24 04:47:57
Seems a bit odd to call dlerror() here since we do
bshaya
2017/03/24 18:55:10
Done.
| |
66 << "() in " << library_path << ": " << error; | |
67 processors_.push_back(create(*processor_config_string, channels)); | |
68 } | |
69 } | |
70 | |
71 PostProcessingPipeline::~PostProcessingPipeline() = default; | |
72 | |
73 int PostProcessingPipeline::ProcessFrames(uint8_t* data, | |
74 int num_frames, | |
75 float current_volume) { | |
76 DCHECK_NE(sample_rate_, kNoSampleRate); | |
77 int total_delay = 0; | |
78 for (auto& processor : processors_) { | |
79 total_delay += processor->ProcessFrames(data, num_frames, current_volume); | |
80 } | |
81 return total_delay; | |
82 } | |
83 | |
84 bool PostProcessingPipeline::SetSampleRate(int sample_rate) { | |
85 sample_rate_ = sample_rate; | |
86 bool result = true; | |
87 for (auto& processor : processors_) { | |
88 result &= processor->SetSampleRate(sample_rate_); | |
89 } | |
90 return result; | |
91 } | |
92 | |
93 int PostProcessingPipeline::GetRingingTimeInFrames() { | |
94 int memory_frames = 0; | |
95 for (auto& processor : processors_) { | |
96 memory_frames += processor->GetRingingTimeInFrames(); | |
97 } | |
98 return memory_frames; | |
99 } | |
100 | |
101 } // namespace media | |
102 } // namespace chromecast | |
OLD | NEW |