| 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 <string> | |
| 8 | |
| 9 #include "base/files/file_path.h" | |
| 10 #include "base/memory/ptr_util.h" | |
| 11 #include "base/scoped_native_library.h" | |
| 12 #include "base/values.h" | |
| 13 #include "chromecast/base/serializers.h" | |
| 14 #include "chromecast/public/media/audio_post_processor_shlib.h" | |
| 15 | |
| 16 namespace chromecast { | |
| 17 namespace media { | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 const int kNoSampleRate = -1; | |
| 22 const char kSoCreateFunction[] = "AudioPostProcessorShlib_Create"; | |
| 23 | |
| 24 } // namespace | |
| 25 | |
| 26 using CreatePostProcessor = AudioPostProcessor* (*)(const std::string&, int); | |
| 27 | |
| 28 PostProcessingPipeline::PostProcessingPipeline( | |
| 29 const base::ListValue* filter_description_list, | |
| 30 int channels) | |
| 31 : sample_rate_(kNoSampleRate) { | |
| 32 if (!filter_description_list) { | |
| 33 return; // Warning logged. | |
| 34 } | |
| 35 for (size_t i = 0; i < filter_description_list->GetSize(); ++i) { | |
| 36 const base::DictionaryValue* processor_description_dict; | |
| 37 CHECK( | |
| 38 filter_description_list->GetDictionary(i, &processor_description_dict)); | |
| 39 std::string library_path; | |
| 40 CHECK(processor_description_dict->GetString("processor", &library_path)); | |
| 41 if (library_path == "null" || library_path == "none") { | |
| 42 continue; | |
| 43 } | |
| 44 const base::Value* processor_config_val; | |
| 45 CHECK(processor_description_dict->Get("config", &processor_config_val)); | |
| 46 CHECK(processor_config_val->is_dict() || processor_config_val->is_string()); | |
| 47 auto processor_config_string = SerializeToJson(*processor_config_val); | |
| 48 | |
| 49 LOG(INFO) << "Creating an instance of " << library_path << "(" | |
| 50 << *processor_config_string << ")"; | |
| 51 libraries_.push_back(base::MakeUnique<base::ScopedNativeLibrary>( | |
| 52 base::FilePath(library_path))); | |
| 53 CHECK(libraries_.back()->is_valid()) | |
| 54 << "Could not open post processing library " << library_path; | |
| 55 CreatePostProcessor create = reinterpret_cast<CreatePostProcessor>( | |
| 56 libraries_.back()->GetFunctionPointer(kSoCreateFunction)); | |
| 57 | |
| 58 CHECK(create) << "Could not find " << kSoCreateFunction << "() in " | |
| 59 << library_path; | |
| 60 processors_.push_back( | |
| 61 base::WrapUnique(create(*processor_config_string, channels))); | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 PostProcessingPipeline::~PostProcessingPipeline() = default; | |
| 66 | |
| 67 int PostProcessingPipeline::ProcessFrames(const std::vector<float*>& data, | |
| 68 int num_frames, | |
| 69 float current_volume, | |
| 70 bool is_silence) { | |
| 71 DCHECK_NE(sample_rate_, kNoSampleRate); | |
| 72 if (is_silence) { | |
| 73 if (!IsRinging()) { | |
| 74 return total_delay_frames_; // Output will be silence. | |
| 75 } | |
| 76 silence_frames_processed_ += num_frames; | |
| 77 } else { | |
| 78 silence_frames_processed_ = 0; | |
| 79 } | |
| 80 | |
| 81 total_delay_frames_ = 0; | |
| 82 for (auto& processor : processors_) { | |
| 83 total_delay_frames_ += | |
| 84 processor->ProcessFrames(data, num_frames, current_volume); | |
| 85 } | |
| 86 return total_delay_frames_; | |
| 87 } | |
| 88 | |
| 89 bool PostProcessingPipeline::SetSampleRate(int sample_rate) { | |
| 90 sample_rate_ = sample_rate; | |
| 91 bool result = true; | |
| 92 for (auto& processor : processors_) { | |
| 93 result &= processor->SetSampleRate(sample_rate_); | |
| 94 } | |
| 95 ringing_time_in_frames_ = GetRingingTimeInFrames(); | |
| 96 silence_frames_processed_ = 0; | |
| 97 return result; | |
| 98 } | |
| 99 | |
| 100 bool PostProcessingPipeline::IsRinging() { | |
| 101 return silence_frames_processed_ < ringing_time_in_frames_; | |
| 102 } | |
| 103 | |
| 104 int PostProcessingPipeline::GetRingingTimeInFrames() { | |
| 105 int memory_frames = 0; | |
| 106 for (auto& processor : processors_) { | |
| 107 memory_frames += processor->GetRingingTimeInFrames(); | |
| 108 } | |
| 109 return memory_frames; | |
| 110 } | |
| 111 | |
| 112 } // namespace media | |
| 113 } // namespace chromecast | |
| OLD | NEW |