Chromium Code Reviews| Index: chromecast/media/cma/backend/alsa/post_processing_pipeline.cc |
| diff --git a/chromecast/media/cma/backend/alsa/post_processing_pipeline.cc b/chromecast/media/cma/backend/alsa/post_processing_pipeline.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..26ea6fcfa4752d2f42d485d0a80e90c2b8d67bee |
| --- /dev/null |
| +++ b/chromecast/media/cma/backend/alsa/post_processing_pipeline.cc |
| @@ -0,0 +1,102 @@ |
| +// Copyright 2017 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chromecast/media/cma/backend/alsa/post_processing_pipeline.h" |
| + |
| +#include <dlfcn.h> |
| + |
| +#include <string> |
| + |
| +#include "base/files/file_path.h" |
| +#include "base/memory/ptr_util.h" |
| +#include "base/scoped_native_library.h" |
| +#include "base/values.h" |
| +#include "chromecast/base/serializers.h" |
| +#include "chromecast/public/media/audio_post_processor_shlib.h" |
| + |
| +namespace chromecast { |
| +namespace media { |
| + |
| +namespace { |
| + |
| +const int kNoSampleRate = -1; |
| +const char kSoCreateFunction[] = "AudioPostProcessorShlib_Create"; |
| + |
| +} // namespace |
| + |
| +using CreatePostProcessor = |
| + std::unique_ptr<AudioPostProcessor> (*)(const std::string&, int); |
| + |
| +PostProcessingPipeline::PostProcessingPipeline( |
| + const base::ListValue* filter_description_list, |
| + int channels) |
| + : sample_rate_(kNoSampleRate) { |
| + if (!filter_description_list) { |
| + return; // Warning logged. |
| + } |
| + for (size_t i = 0; i < filter_description_list->GetSize(); ++i) { |
| + const base::DictionaryValue* processor_description_dict; |
| + CHECK( |
| + filter_description_list->GetDictionary(i, &processor_description_dict)); |
| + std::string library_path; |
| + CHECK(processor_description_dict->GetString("processor", &library_path)); |
| + if (library_path == "null" || library_path == "none") { |
| + continue; |
| + } |
| + const base::Value* processor_config_val; |
| + CHECK(processor_description_dict->Get("config", &processor_config_val)); |
| + CHECK(processor_config_val->is_dict() || processor_config_val->is_string()); |
| + auto processor_config_string = SerializeToJson(*processor_config_val); |
| + |
| + LOG(INFO) << "Creating an instance of " << library_path << "(" |
| + << *processor_config_string << ")"; |
| + if (libraries_.find(library_path) == libraries_.end()) { |
| + libraries_[library_path] = base::MakeUnique<base::ScopedNativeLibrary>( |
| + base::FilePath(library_path)); |
| + } |
| + auto& library = libraries_[library_path]; |
| + CHECK(library->is_valid()) << "Could not open post processing library " |
| + << library_path << ": " << dlerror(); |
| + CreatePostProcessor create = reinterpret_cast<CreatePostProcessor>( |
| + library->GetFunctionPointer(kSoCreateFunction)); |
| + |
| + char* error; |
| + 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.
|
| + << "() in " << library_path << ": " << error; |
| + processors_.push_back(create(*processor_config_string, channels)); |
| + } |
| +} |
| + |
| +PostProcessingPipeline::~PostProcessingPipeline() = default; |
| + |
| +int PostProcessingPipeline::ProcessFrames(uint8_t* data, |
| + int num_frames, |
| + float current_volume) { |
| + DCHECK_NE(sample_rate_, kNoSampleRate); |
| + int total_delay = 0; |
| + for (auto& processor : processors_) { |
| + total_delay += processor->ProcessFrames(data, num_frames, current_volume); |
| + } |
| + return total_delay; |
| +} |
| + |
| +bool PostProcessingPipeline::SetSampleRate(int sample_rate) { |
| + sample_rate_ = sample_rate; |
| + bool result = true; |
| + for (auto& processor : processors_) { |
| + result &= processor->SetSampleRate(sample_rate_); |
| + } |
| + return result; |
| +} |
| + |
| +int PostProcessingPipeline::GetRingingTimeInFrames() { |
| + int memory_frames = 0; |
| + for (auto& processor : processors_) { |
| + memory_frames += processor->GetRingingTimeInFrames(); |
| + } |
| + return memory_frames; |
| +} |
| + |
| +} // namespace media |
| +} // namespace chromecast |