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(uint8_t* 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 |