1 // Copyright (c) 2012 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 #ifndef REMOTING_HOST_LINUX_AUDIO_PIPE_READER_H_ 6 #define REMOTING_HOST_LINUX_AUDIO_PIPE_READER_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 12 #include "base/files/file.h" 13 #include "base/files/file_descriptor_watcher_posix.h" 14 #include "base/files/file_path.h" 15 #include "base/files/file_path_watcher.h" 16 #include "base/macros.h" 17 #include "base/memory/ref_counted.h" 18 #include "base/memory/ref_counted_memory.h" 19 #include "base/observer_list_threadsafe.h" 20 #include "base/single_thread_task_runner.h" 21 #include "base/time/time.h" 22 #include "base/timer/timer.h" 23 #include "remoting/proto/audio.pb.h" 24 25 namespace remoting { 26 27 struct AudioPipeReaderTraits; 28 29 // AudioPipeReader class reads from a named pipe to which an audio server (e.g. 30 // pulseaudio) writes the sound that's being played back and then sends data to 31 // all registered observers. 32 class AudioPipeReader 33 : public base::RefCountedThreadSafe<AudioPipeReader, 34 AudioPipeReaderTraits> { 35 public: 36 // PulseAudio's module-pipe-sink must be configured to use the following 37 // parameters for the sink we read from. 38 static const AudioPacket_SamplingRate kSamplingRate = 39 AudioPacket::SAMPLING_RATE_48000; 40 static const AudioPacket_BytesPerSample kBytesPerSample = 41 AudioPacket::BYTES_PER_SAMPLE_2; 42 static const AudioPacket_Channels kChannels = AudioPacket::CHANNELS_STEREO; 43 44 class StreamObserver { 45 public: 46 virtual void OnDataRead(scoped_refptr<base::RefCountedString> data) = 0; 47 }; 48 49 // |task_runner| specifies the IO thread to use to read data from the pipe. 50 static scoped_refptr<AudioPipeReader> Create( 51 scoped_refptr<base::SingleThreadTaskRunner> task_runner, 52 const base::FilePath& pipe_path); 53 54 // Register or unregister an observer. Each observer receives data on the 55 // thread on which it was registered and guaranteed not to be called after 56 // RemoveObserver(). 57 void AddObserver(StreamObserver* observer); 58 void RemoveObserver(StreamObserver* observer); 59 60 private: 61 friend class base::DeleteHelper<AudioPipeReader>; 62 friend class base::RefCountedThreadSafe<AudioPipeReader>; 63 friend struct AudioPipeReaderTraits; 64 65 AudioPipeReader(scoped_refptr<base::SingleThreadTaskRunner> task_runner, 66 const base::FilePath& pipe_path); 67 ~AudioPipeReader(); 68 69 void StartOnAudioThread(); 70 void OnDirectoryChanged(const base::FilePath& path, bool error); 71 void TryOpenPipe(); 72 void StartTimer(); 73 void DoCapture(); 74 void WaitForPipeReadable(); 75 76 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 77 base::FilePath pipe_path_; 78 79 // Watcher for the directory that contains audio pipe we are reading from, to 80 // monitor when pulseaudio creates or deletes it. 81 base::FilePathWatcher file_watcher_; 82 83 base::File pipe_; 84 base::RepeatingTimer timer_; 85 scoped_refptr<base::ObserverListThreadSafe<StreamObserver>> observers_; 86 87 // Size of the pipe buffer. 88 int pipe_buffer_size_; 89 90 // Period between pipe reads. 91 base::TimeDelta capture_period_; 92 93 // Time when capturing was started. 94 base::TimeTicks started_time_; 95 96 // Stream position of the last capture in bytes with zero position 97 // corresponding to |started_time_|. Must always be a multiple of the sample 98 // size. 99 int64_t last_capture_position_; 100 101 // Bytes left from the previous read. 102 std::string left_over_bytes_; 103 104 std::unique_ptr<base::FileDescriptorWatcher::Controller> 105 pipe_watch_controller_; 106 107 DISALLOW_COPY_AND_ASSIGN(AudioPipeReader); 108 }; 109 110 // Destroys |audio_pipe_reader| on the audio thread. 111 struct AudioPipeReaderTraits { 112 static void Destruct(const AudioPipeReader* audio_pipe_reader); 113 }; 114 115 } // namespace remoting 116 117 #endif // REMOTING_HOST_LINUX_AUDIO_PIPE_READER_H_ 118